なぜcast
ingstring
がubyte[]
D で安全ではない力になるのですか?
また、同じケースでstd.conv:to
unsafe と notrow を使用しているのはなぜですか?
ubyte[]
反対( UTF-8へのキャスト)は安全でなくスローする必要があることをよく理解できますが、この場合はそうではありませんか?
これらの個々のバイトを安全に調査できないのはなぜですか?
string -> ubyte は、文字列の不変性をキャストするため、セーフ モードでは許可されません。cast(immutable(ubyte)[]) some_string
許可されています。を実行して、文字列のバイトを確認することもできますforeach(char c; some_string) { /* look at c */ }
。
to!(ubyte[])(some_string)
スローすることはできますが、セーフモードでも機能しました。その理由は、std.array のアペンダー ヘルパー関数が正しく nothrow としてマークされていないためです。フォボスバグ。std/array.d の 2662 行目 (dmd 2.064.2) に nothrow を追加すると、nothrow としてもコンパイルされます。
@safe
UTF-8 と ASCII とは何の関係もありません。@safe
メモリの安全性と関係があります。解放されたメモリや破損したメモリで操作しないようなものを保証しています。多くのタイプのキャストは安全ではないと見なされ@system
ます。メモリの安全性に違反するリスクがあるためです。プログラマは、キャストが実際にメモリの安全性に違反していないことを確認し@trusted
、コンパイラに実際に安全で、@safe
コードで使用できます。
へのキャストに関しては、そのようにキャストするstring
ことは型システムを回避しています。コードがデータを変更していないことを保証する必要があり、そうでない場合はコンパイラの保証に違反していることになり、バグが発生することになります。私は見ることをお勧めしますubyte[]
immutable
簡単に言うと、本当に必要な場合を除き、捨てconst
ないimmutable
でください。あなたは自分が何をしているのかを知っています.
std.conv.to
dup
変換を行うために必要な場合は配列になるため、 と同じ値を持つto!(ubyte[])("hello world")
newになりますが、同じ配列にはならないため、型システムに違反しません。だった場合、配列をキャストできますが、可変配列に変換している限りはできません。ubyte[]
"hello world"
to!(immutable(ubyte)[])("hello world")
とについてto!(ubyte[])("hello world")
は、実装の問題です。文字をデコードする必要はないはずなので、 になることは間違いなく可能であると思いますが、基本的な実装はそれをサポートしていません。おそらく、Phobos が使用する低レベルのものの多くが原因です、、またはまだサポートしていません。その状況は改善されつつあります (たとえば、dmd 2.064 では、状況によっては改善される可能性があります) が、まだまだ先は長いです。@system
nothrow
@safe
nothrow
@safe
pure
nothrow
format
pure
「個々のバイトの調査」に関しては、変換を行う必要がある理由がまったくわかりません。string
の要素を反復するだけです。それらはchar
であり、これは とまったく同じサイズと符号ubyte
です。string
しかし、割り当てずに の配列として操作したい場合はubyte
、同じ constness にキャストするだけですstring
。
auto arr = cast(immutable(ubyte)[])"hello world";
また
auto arr = to!(immutable(ubyte)[])("hello world");
std.string.representationも参照してください。