せず手書きで実装することになるだろう。ようにフォーマットされてしまう。トレイトは後述のように自前で実装してやる必要がある。実装があると叱られるという最悪の実装なので、無効化するしかない。問題として上流で認識されてはいるので、そのうち改善されることが期待できる。#[repr(transparent)]これが型定義で最も重要な部分である。型の内部表現についての指定をコンパイラに与えるものであり、たとえば「特定のアラインメントを持たねばならない」や「C言語における構造体と同等のメモリレイアウトを持たねばならない」などの指定ができる。型と同じメモリレイアウトを持つ必要がある」といったところである。この指定は未定義動作を防ぐために不可欠なものであり[7]、決して忘れてはいけない。欠如が未定義動作を引き起こす理由を理解するには、型のメモリレイアウトを考える必要がある。低レベルでは文字列の長さ(バイト長)と先頭文字へのポインタの組として考えることができる。同じであるとは保証されない。同じかもしれないし、違うかもしれない。保証されている性質はごく僅かであり、ここでは役に立たない。よる型変換が安全に行えなくなってしまうのである。メモリレイアウトが一致しているからこそ可能である。配列と見做す」という解釈の切り替えが発生しているのである。値であるかのように解釈する」ことができるしかし、メモリレイアウトが一致していない場合、この解釈の切り替えが不正な操作となってしまう。長さの後にポインタを持っているとする。文字列と見做す」という挙動になってしまうのである。この操作は未定義動作であり、不正なメモリアクセスや予期せぬコンパイル結果を発生させるおそれがある。指定されていない型のメモリレイアウトの決定について裁量を持っており、またその後方互換性も担保されない。ようにしただけではメモリレイアウトの互換性は保証されないし、もしある環境のあるバージョンのコンパイラでたまたま互換性があったとしても、他の環境や別のバージョンにおいて同様に互換性があるとは限らないのである。必要な理由は「参照型のメモリレイアウトの互換性を保証することで、参照型の読み替えによるキャストを安全に実装可能にするため」であると説明できる。言っても、本当にメモリレイアウトを変えることがあるの?知らん。知らないが、レイアウトを変えるに足る現実的なシナリオを妄想することはできる。長さを取得する処理が多く、中身の文字列にアクセスすることはほとんどない」というユースケースだったとしよう。コンパイラやプロファイラが解析によってこのことを認識した場合、ポインタよりも長さ情報を先頭に置くことで、一部アーキテクチャにおいてアドレス計算を省略し、長さ情報へのアクセスの高速化などが可能になるかもしれない。メモリレイアウトが非互換になる可能性もあるというのがポイントである。保証できないことを勝手に確信してはいけない。特筆すべきことはない。可能であることがスライス型の定義との違いである。してしまいがちなのだが、本当にそれでいいのかよく考えるべきである。独自スライス型の定義という文脈では、たとえば「空でない配列のスライス型」とか「C言語の識別子であるような文字列のスライス型」みたいなものを定義したくなるかもしれない。いった場合、デフォルトとして空の配列や空文字列が生成されては全てが破綻することになる。型の定義ができたら、次は基本的な型変換を実装しよう。追加の制約なしの型の場合まずは追加の制約なしの型から考えよう。先の節で説明したように、スライス型の変換は解釈の切り替えによって行う。本質的に不可避であることに留意せよ。任意だが、私は付けることにしている。関数は値の解釈の変更以外の実務を一切行わず、また副作用がないため利用しない解釈変更を行うことはナンセンスだからである。トレイトを実装する際に利用できる。追加の制約があって値の変換が失敗しうる場合、多少の下準備が必要になる。検査を行う関数と、そこから返すエラー型を用意する。エラーの出たバイト位置と、その場所の値を持つ。内部の型のみから作る場合エラー型ができたら、これを使って検査が書ける。}}与えられたデータが型の制約を満たすか確認する。エラー型をどこまで詳細にするかにもよるが、ちょっとしたパーサのようなものを書くことになる。この検査はちょっとしたパーサのようなものになるかもしれないが、大事なのはエラーかそうでないか、エラーならどのようなエラーか、それだけである。返すと便利なのではと考える人もいるかもしれない。入力文字列を借用しっぱなしになっているのは少々鬱陶しい。値として返しても総合的には大したメリットにならない場合が多いだろう。検査ができるようになったら次は値の変換である。セクションで提示することを推奨している。マクロを突っ込んでデバッグビルド時にだけ強制的に検査を行うという手がある。二重に検査が行われる。これが気になるようなら、関数を分離するという手もある。そこまですべきかは微妙かもしれないが。}}検査なしの変換が実装できたら、次は検査ありの安全な変換である。戻り値の型に注意して実装する。}}制約を満たす文字列であれば読み替える。制約を満たさなければ、読み替えずエラーとする。これで、効率的だが安全性の検査がスキップされるものと、検査が必ず強制される安全なものが実装できた。指定が付いているため、関数側で改めて指定する必要はない。無意味だと警告される。トレイトを実装する際に利用できる。文字列はバイト列として扱いたい場合も多いだろう。