私はしばしばnewtypeパターンを使いますが、私はmy_type.0.call_to_whatever(...)
と書いてうんざりです。私はDeref
の特性を実装しようとしているのですが、単純なコードを書くことができるので、私のnewtypeはあたかも基底型であるかのように使うことができるからです。:Derefをnewtypeに実装することは悪い習慣と考えられますか?
use std::ops::Deref;
type Underlying = [i32; 256];
struct MyArray(Underlying);
impl Deref for MyArray {
type Target = Underlying;
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn main() {
let my_array = MyArray([0; 256]);
println!("{}", my_array[0]); // I can use my_array just like a regular array
}
これは良いか悪い習慣ですか?どうして?欠点は何ですか?
私は少なくとも「Deref」に関して同意しなければなりません。私のnewtypeの大部分はファンシーコンストラクタとしてのみ存在するため、一定の不変条件を満たすという静的保証でデータを渡すことができます。つまり、オブジェクトが構築されたら、もはやnewtypeは本当に気にしません。基礎データのみです。どこでもパターンを一致させることは雑音に過ぎず、私が心配するかもしれないすべての方法を委任することも同様です。私は、型がDerefMutではなくDerefMutを実装するのは驚くかもしれないと考えていますが、理由のために別の特性です... – ildjarn
@ indjarn * 'DerefMut'を実装すると、newtypeフィールドの可視性にかかわらず、誰でも簡単にそれらを変更できるので、不変量を静的に保証することはできません。 'Deref'だけを実装すれば、人々はあなたのデータを突き止めることができます。これにより重大な損害は発生しませんが、公開する必要があるAPIよりも広いAPIを提示することがよくあります。 – Shepmaster
"*これは重大な損害を引き起こしてはいけませんが、あなたが公開する必要があるAPIよりも広いAPIを提供することがあります。*" std :: str'以上のIMO;例えば、あなたはしばしば、その事実を曖昧にする(/抽象化しようとする)ことは無意味ですが、維持する厳格な不変条件(UTF-8)があるプリミティブ型のシーケンスを扱うことがあります。私はそれについて強く感じない。私はちょうど "悪い練習"がかなり強くそれを入れているように感じる。 : - ](編集: 'deref_mut'を安全にできないなら、おそらく' Deref'sansの 'DerefMut'という難問がないので強く感じるでしょう) – ildjarn