Rust: 専門分野の远跡の問題RFC 1210

䜜成日 2016幎02月23日  Â·  236コメント  Â·  ゜ヌス: rust-lang/rust

これは特殊化の远跡の問題ですrust-lang / rfcs1210。

䞻な実装手順

  • [x]土地https://github.com/rust-lang/rust/pull/30652=
  • []生涯掟遣に関する制限珟圚は健党性の穎
  • [] default impl https://github.com/rust-lang/rust/issues/37653
  • []関連する定数ずの統合
  • []境界が垞に適切に適甚されるずは限りたせんhttps://github.com/rust-lang/rust/issues/33017
  • []芪にdefaultメンバヌがいない堎合、空のimplを蚱可する必芁がありたすか https://github.com/rust-lang/rust/issues/48444
  • []「垞に適甚可胜」な実装https://github.com/rust-lang/rust/issues/48538
  • []特殊化グラフの䜜成に関する正確なサむクル条件を蚘述しおテストしたすたずえば、今日ここに非垞に泚意深いロゞックがあるこずを瀺したこのコメントを参照しおください

RFCからの未解決の質問

  • 関連する型はたったく特殊化する必芁がありたすか
  • 投圱によっおdefault type明らかになるのはい぀ですか typeck䞭にはありたせんか たたは単圢の堎合
  • デフォルトのトレむトアむテムはdefault ぀たり特殊化可胜ず芋なされるべきですか
  • default impl すべおのアむテムがdefault たたはpartial impl  defaultがオプトむンの堎合が必芁です。 default implが制限されおいる関連する䟋に぀いおは、 https //github.com/rust-lang/rust/issues/37653#issuecomment-616116577を参照しお
  • 生涯ディスパッチ可胜性にどのように察凊する必芁がありたすか

珟圚実装されおいるspecialization機胜は正しくないこずに泚意しおください。぀たり、 specialization unsafeコヌドがないず未定矩の動䜜が発生する可胜性がありたす。 min_specializationは、ほずんどの萜ずし穎を回避したす。

A-specialization A-traits B-RFC-approved B-RFC-implemented B-unstable C-tracking-issue F-specialization T-lang

最も参考になるコメント

私は自分が開発しおいる実隓ラむブラリで#[min_specialization]しおいるので、自分の経隓を共有したいず思いたした。 目暙は、特殊化を最も単玔な圢匏で䜿甚するこずです。぀たり、䞀般的なケヌスよりも実装が高速な狭いケヌスをいく぀か持぀こずです。 特に、䞀般的なケヌスで暗号化アルゎリズムを䞀定時間で実行するが、すべおの入力がPublicずマヌクされおいる堎合は、より高速な可倉時間で実行される特殊なバヌゞョンがありたす公開されおいる堎合は公開されおいないため実行時間を介しおそれらに関する情報を挏らすこずに泚意しおください。 さらに、䞀郚のアルゎリズムは、楕円曲線点が正芏化されおいるかどうかに応じお高速になりたす。 これを機胜させるには、たず

#![feature(rustc_attrs, min_specialization)]

次に、最倧限に最小限の特殊化で説明されおいるように_特殊化述語_特性を䜜成する必芁がある堎合は、特性宣蚀に#[rustc_specialization_trait]マヌクを付けたす。

私のすべおの特殊化はこのファむルで行われ、䟋です。

この機胜は機胜し、私が必芁ずしおいるこずを正確に実行したす。 これは明らかにrustc内郚マヌカヌを䜿甚しおいるため、譊告なしに砎損する傟向がありたす。

フィヌドバックの唯䞀の吊定的な点は、 defaultキヌワヌドが意味をなさないず感じおいるこずです。 基本的に、珟圚default意味するのは、「このimplは特殊化可胜であるため、このimplのサブセットをカバヌするimplを、競合するimplではなく特殊化ずしお解釈する」ずいうこずです。 問題は、非垞に奇劙なコヌドに぀ながるこずです。

https://github.com/LLFourn/secp256kfun/blob/6766b60c02c99ca24f816801fe876fed79643c3a/secp256kfun/src/op.rs#L196 -L206

ここで、2番目のimplは最初のimplを特殊化しおいたすが、これもdefaultです。 defaultの意味が倱われおいるようです。 残りのimplを芋るず、どのimplがどれを専門にしおいるのかを理解するのは非垞に困難です。 さらに、既存のものず重耇する誀ったimplを䜜成したずき、どこが間違っおいるのかを理解するのが難しいこずがよくありたした。

すべおが特殊化されおいお、䜕かを特殊化するずきに、どのimplを特殊化するかを正確に宣蚀するず、これはより簡単になるように思えたす。 RFCの䟋を私が考えおいたものに倉換したす。

impl<A, T> Extend<A, T> for Vec<A> where T: IntoIterator<Item=A>
{
    // no need for default
    fn extend(&mut self, iterable: T) {
        ...
    }
}

// We declare explicitly which impl we are specializing repeating all type bounds etc
specialize impl<A, T> Extend<A, T> for Vec<A> where T: IntoIterator<Item=A>
    // And then we declare explicitly how we are making this impl narrower with ‘when’.
    // i.e. This impl is like the first except replace all occurances of ‘T’ with ‘&'a [A]’
    when<'a> T = &'a [A]
{
    fn extend(&mut self, iterable: &'a [A]) {
        ...
    }
}

党おのコメント236件

いく぀かの远加の未解決の質問

  • 専門性に照らしお、孀立したルヌルを再怜蚎する必芁がありたすか 今、物事をより柔軟にする方法はありたすか
  • RFCの「連鎖埋」を、いわゆる「栌子芏則」のような、より衚珟力豊かなものに拡匵する必芁がありたすか
  • 䞊蚘の䞡方に関連しお、吊定的な掚論はどのように物語に適合したすか 特殊化/孀立したルヌルを巧みに䜿甚するこずで、必芁な吊定的な掚論を回埩できたすか、それずももっずファヌストクラスにする必芁がありたすか

専門化によっお孀立したルヌルが倉わるかどうかはわかりたせん。

  • 「リンク」孀立ルヌルは同じたたである必芁がありたす。そうしないず、安党なリンクが埗られないためです。
  • 「将来の互換性」の孀立したルヌルは倉曎されるべきではないず思いたす。 あなたの䞋に専門倖のimplを远加するこずは、それでも重倧な倉曎になりたす。

さらに悪いこずに、「将来の互換性」の孀立したルヌルは、クレヌト間の特殊化をかなり厳しく管理し続けたす。 それらがないず、メ゜ッドを開いたたたにするdefault-implsはさらに悪化したす。

私は明癜な吊定的な掚論が奜きではありたせんでした。 私は、専門化が提䟛する完党な吊定的な掚論は良い劥協点だず思いたす。

この実装は、実装された特殊化で蚱可する必芁がありたすか それずも私は䜕かが足りないのですか
http://is.gd/3Ul0pe

これず同じように、コンパむルされるこずを期埅しおいたした http 

関連するタむプが関係しおいる堎合、オヌバヌラップを決定する際にいく぀かの癖があるようです。 これはコンパむルされたす http  http 

これが私が特殊化しおコンパむルするこずを期埅したコヌドの䞀郚です

http://is.gd/3BNbfK

#![feature(specialization)]

use std::str::FromStr;

struct Error;

trait Simple<'a> {
    fn do_something(s: &'a str) -> Result<Self, Error>;
}

impl<'a> Simple<'a> for &'a str {
     fn do_something(s: &'a str) -> Result<Self, Error> {
        Ok(s)
    }
}

impl<'a, T: FromStr> Simple<'a> for T {
    fn do_something(s: &'a str) -> Result<Self, Error> {
        T::from_str(s).map_err(|_| Error)
    }
}

fn main() {
    // Do nothing. Just type check.
}

コンパむルは、実装の競合を理由にコンパむラで倱敗したす。 &strはFromStr実装しおいないため、競合が発生しないこずに泚意しおください。

@sgrif

最初の2぀の䟋を芋る時間がありたした。 これが私のメモです。

䟋1

最初のケヌスでは、次のようになりたす。

  • FromSqlRow<ST, DB> for T where T: FromSql<ST, DB>
  • FromSqlRow<(ST, SU), DB> for (T, U) where T: FromSqlRow<ST, DB>, U: FromSqlRow<SU, DB>,

問題は、これらのimplが重耇しおいるが、どちらも他よりも具䜓的ではないこずです。

  • T: FromSql<ST, DB>が存圚する可胜性がありたすが、 Tはペアではありたせんしたがっお、最初のimplず䞀臎したすが、2番目のimplずは䞀臎したせん。
  • あなたは朜圚的に(T, U)持぀こずができたすここで

    • T: FromSqlRow<ST, DB> 、

    • U: FromSqlRow<SU, DB> 、しかし_not_

    • (T, U): FromSql<(ST, SU), DB>

    • したがっお、2番目のimplは䞀臎したすが、最初のimplは䞀臎したせん

  • 次のような(T, U)持぀こずができるため、2぀のimplは重耇したす。

    • T: FromSqlRow<ST, DB>

    • U: FromSqlRow<SU, DB>

    • (T, U): FromSql<(ST, SU), DB>

これは、lattice implsが蚱容するような状況です。重耇するケヌスに察しお、3番目のimplを蚘述し、それが䜕をすべきかを蚀う必芁がありたす。 あるいは、負の特性の実装は、重耇を陀倖する方法、たたは䞀臎する可胜性のある埮調敎を行う方法を提䟛する堎合がありたす。

䟋2

あなたが持っおいる

  • Queryable<ST, DB> for T where T: FromSqlRow<ST, DB>
  • Queryable<Nullable<ST>, DB> for Option<T> where T: Queryable<ST, DB>

Option<T>を䜿甚できるため、これらは重耇しおいたす。

  • T: Queryable<ST, DB>
  • Option<T>: FromSqlRow<Nullable<ST>, DB>

しかし、どちらのimplもより具䜓的ではありたせん。

  • あなたは持぀こずができたすTようにT: FromSqlRow<ST, DB>が、 TないOption<U> 第1、第2のimplず䞀臎するではなく
  • T: Queryable<ST, DB>ようにOption<T>を持぀こずができたすが、 Option<T>: FromSqlRow<Nullable<ST>, DB>はできたせん

@SergioBenitez

コンパむルは、実装の競合を理由にコンパむラで倱敗したす。 &strはFromStr実装しおいないため、競合が発生しないこずに泚意しおください。

問題は、コンパむラが&strが将来FromStrを実装するようになるかもしれないず控えめに想定しおいるこずです。 この䟋ではそれはばかげおいるように芋えるかもしれたせんが、䞀般に、新しいimplを垞に远加し、それらのimplを远加するずきにダりンストリヌムコヌドが壊れないように保護したいず考えおいたす。

これは控えめな遞択であり、時間をかけおリラックスしたいず思うかもしれたせん。 ここで背景を取埗できたす

この2぀のケヌスを明確にしおいただきありがずうございたす。 今では完党に理にかなっおいたす

2016幎3月22日火曜日、午埌6時34分アヌロンテュヌロン[email protected]は次のように曞いおいたす。

@SergioBenitez https://github.com/SergioBenitez

コンパむルは、実装の競合を理由にコンパむラで倱敗したす。 泚意
strはFromStrを実装しおいないため、競合が発生するこずはありたせん。

問題は、コンパむラが保守的にstrを想定しおいるこずです。
将来的にFromStrを実装するようになるかもしれたせん。 それはばかげおいるように芋えるかもしれたせん
この䟋ですが、䞀般的には、垞に新しいimplを远加したす。
これらのimplを远加するずきに、ダりンストリヌムコヌドが壊れないように保護したす。

これは控えめな遞択であり、私たちがリラックスしたいず思うかもしれないものです
時間ずずもに。 ここで背景を取埗できたす

-
http://smallcultfollowing.com/babysteps/blog/2015/01/14/little-orphan-impls/

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信するか、GitHubで衚瀺しおください
https://github.com/rust-lang/rust/issues/31844#issuecomment -200093757

@aturon

問題は、コンパむラが、strが将来FromStrを実装するようになる可胜性があるず控えめに想定しおいるこずです。 この䟋ではそれはばかげおいるように芋えるかもしれたせんが、䞀般に、新しいimplを垞に远加し、それらのimplを远加するずきにダりンストリヌムコヌドが壊れないように保護したいず考えおいたす。

これはたさに専門分野が察凊しようずしおいるこずではありたせんか 専門で、私はそれを期埅する堎合でもの実装FromStrのための&str 、将来的に远加されたしたが、盎接実装Simple圢質の&str優先されたす。

@SergioBenitezは、より䞀般的なimplにdefault fnを入れる必芁がありたす。 君の
䟋は特殊化されおいたせん。

2016幎3月22日火曜日、午埌6時54分セルゞオベニテス[email protected]
曞きたした

@aturon https://github.com/aturon

問題は、コンパむラが保守的にstrを想定しおいるこずです。
将来的にFromStrを実装するようになるかもしれたせん。 これにはばかげおいるように芋えるかもしれたせん
䟋ですが、䞀般的には、垞に新しいimplを远加したす。
これらのimplを远加するずきに、ダりンストリヌムコヌドが壊れないように保護したす。

これはたさに専門分野が察凊しようずしおいるこずではありたせんか ず
専門分野では、FromStrの実装であっおも
strは将来远加され、の盎接実装
strの特性が優先​​されたす。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信するか、GitHubで衚瀺しおください
https://github.com/rust-lang/rust/issues/31844#issuecomment -200097995

「デフォルト」のトレむトアむテムが自動的にdefaultず芋なされるのimplを緩和するずずもに、Haskellなどのような特性の䞡方のパラメトリシティが必芁になる堎合がありたす。 たた、 defaultように、簡単にgrepするこずはできたせん。 defaultキヌワヌドを入力し、デフォルトの実装を指定するこずは難しくありたせんが、そのたた分離するこずはできたせん。 たた、蚀語を明確にしたい堎合は、これらの「デフォルト」の特性アむテムの名前を、ドキュメント内の「特性提案」アむテムに倉曎できたす。

32999コメントからの泚意ラティスルヌルを䜿甚するたたは負の制玄を蚱可する堎合、䜕かのさらなる特殊化を防ぐための「䞭間特性を䜿甚する」トリックは機胜しなくなりたす。

@Stebalien

なぜそれが機胜しないのですか このトリックは、専門分野を私的な特性に限定したす。 あなたがそれにアクセスできない堎合、あなたは私的な特性を専門にするこずはできたせん。

@ arielb1ああ。 いい芖点ね。 私の堎合、その特性は私的なものではありたせん。

「孀立した䞊䜍互換性+コヒヌレンスルヌルのために倖郚゜ヌスを専門化できない」ずいう掚論は、特に興味深いたたは有甚ではないず思いたす。 特に、特定の䞀貫性ルヌルにコミットしない堎合。

オヌバヌラむドされたdefault implにアクセスする方法はありたすか もしそうなら、これはテストの構築に圹立぀可胜性がありたす。 契玄による蚭蚈ずlibhoareを参照しおください。

型チェック䞭にデフォルトの関連付けられた型の投圱を蚱可するず、コンパむル時に型の䞍等匏を適甚できたす //gist.github.com/7c081574958d22f89d434a97b626b1e4

#![feature(specialization)]

pub trait NotSame {}

pub struct True;
pub struct False;

pub trait Sameness {
    type Same;
}

mod internal {
    pub trait PrivSameness {
        type Same;
    }
}

use internal::PrivSameness;

impl<A, B> Sameness for (A, B) {
    type Same = <Self as PrivSameness>::Same;
}

impl<A, B> PrivSameness for (A, B) {
    default type Same = False;
}
impl<A> PrivSameness for (A, A) {
    type Same = True;
}

impl<A, B> NotSame for (A, B) where (A, B): Sameness<Same=False> {}

fn not_same<A, B>() where (A, B): NotSame {}

fn main() {
    // would compile
    not_same::<i32, f32>();

    // would not compile
    // not_same::<i32, i32>();
}

@burdgesのコメントごずに線集

CloudFlareを䜿甚しおいるためにTorナヌザヌに察しお解決されないため、おそらくfyi @ rphmeierは

@burdges FWIW play.rust-lang.org自䜓は、「短瞮」ボタンにis.gdを䜿甚しおいたす。

ただし、おそらく倉曎できたす https 

このように䜿甚したすhttps://is.gd/Ux6FNs

#![feature(specialization)]
pub trait Foo {}
pub trait Bar: Foo {}
pub trait Baz: Foo {}

pub trait Trait {
    type Item;
}

struct Staff<T> { }

impl<T: Foo> Trait for Staff<T> {
    default type Item = i32;
}

impl<T: Foo + Bar> Trait for Staff<T> {
    type Item = i64;
}

impl<T: Foo + Baz> Trait for Staff<T> {
    type Item = f64;
}

fn main() {
    let _ = Staff { };
}

゚ラヌ

error: conflicting implementations of trait `Trait` for type `Staff<_>`: [--explain E0119]
  --> <anon>:20:1
20 |> impl<T: Foo + Baz> Trait for Staff<T> {
   |> ^
note: conflicting implementation is here:
  --> <anon>:16:1
16 |> impl<T: Foo + Bar> Trait for Staff<T> {
   |> ^

error: aborting due to previous error

将来のspecializationはこれをサポヌトしたすか珟圚、他の皮類の実装はありたすか

@zitsen

T: Foo + BarもT: Foo + Bazも他よりも特殊化されおいないため、これらの実装は珟圚の特殊化蚭蚈では蚱可されおいたせん。 ぀たり、 T: Foo + Bar + Baz堎合、どのimplが「勝぀」べきかは明確ではありたせん。

T: Foo + Bar + Baz含意を_たた_䞎えるこずができ、したがっお曖昧さを解消できる、より衚珟力豊かなシステムに぀いおいく぀かの考えがありたすが、それはただ完党には提案されおいたせん。

負の特性がtrait Baz: !Bar到達する堎合は、それを特殊化ずずもに䜿甚しお、Barを実装するタむプのセットずBazを実装するタむプのセットが区別されお個別に特殊化できるこずを蚌明するこずもできたす。

@rphmeierの返信は私がたさに望んでいるもののようです。 T: Foo + Bar + Baz implsも圹立ちたす。

これを無芖しおください。私はただ私のケヌスず関係があり、 specializationやその他の機胜が䞊陞するのをい぀も楜しみにしおいたす。

ありがずう@ aturon @ rphmeier 。

私は最近専門分野で遊んでいたす、そしお私はこの奇劙なケヌスに出くわしたした

#![feature(specialization)]

trait Marker {
    type Mark;
}

trait Foo { fn foo(&self); }

struct Fizz;

impl Marker for Fizz {
    type Mark = ();
}

impl Foo for Fizz {
    fn foo(&self) { println!("Fizz!"); }
}

impl<T> Foo for T
    where T: Marker, T::Mark: Foo
{
    default fn foo(&self) { println!("Has Foo marker!"); }
}

struct Buzz;

impl Marker for Buzz {
    type Mark = Fizz;
}

fn main() {
    Fizz.foo();
    Buzz.foo();
}

コンパむラ出力

error: conflicting implementations of trait `Foo` for type `Fizz`: [--explain E0119]
  --> <anon>:19:1
19 |> impl<T> Foo for T
   |> ^
note: conflicting implementation is here:
  --> <anon>:15:1
15 |> impl Foo for Fizz {
   |> ^

ベビヌサヌクル

䞊蚘はコンパむルする必芁があるず思いたす。実際に意図したずおりに機胜する2぀の興味深いバリ゚ヌションがありたす。

1 where T::Mark: Fizzバりンドの削陀

impl<T> Foo for T
    where T: Marker //, T::Mark: Fizz
{
    // ...
}

ベビヌサヌクル

2「特性バむンド゚むリアス」の远加

trait FooMarker { }
impl<T> FooMarker for T where T: Marker, T::Mark: Foo { }

impl<T> Foo for T where T: FooMarker {
    // ...
}

ベビヌサヌクル

 Markerが別のクレヌトで定矩されおいる堎合、これは機胜したせん。この䟋のリポゞトリを参照しおください

たた、この問題は䜕らかの圢で20400に関連しおいる可胜性があるず思いたす

線集私はこれに぀いおの問題を開きたした36587

スペシャラむれヌションで問題が発生しおいたす。 それが実装の問題なのか、特殊化の指定方法の問題なのかわからない。

use std::vec::IntoIter as VecIntoIter;

pub trait ClonableIterator: Iterator {
    type ClonableIter;

    fn clonable(self) -> Self::ClonableIter;
}

impl<T> ClonableIterator for T where T: Iterator {
    default type ClonableIter = VecIntoIter<T::Item>;

    default fn clonable(self) -> VecIntoIter<T::Item> {
        self.collect::<Vec<_>>().into_iter()
    }
}

impl<T> ClonableIterator for T where T: Iterator + Clone {
    type ClonableIter = T;

    #[inline]
    fn clonable(self) -> T {
        self
    }
}

ベビヌサヌクル
ちなみに、このコヌドが最終的にstdlibに到達したずしたらいいでしょう

このコヌドは次の堎合に倱敗したす

error: method `clonable` has an incompatible type for trait:
 expected associated type,
    found struct `std::vec::IntoIter` [--explain E0053]
  --> <anon>:14:5
   |>
14 |>     default fn clonable(self) -> VecIntoIter<T::Item> {
   |>     ^

戻り倀をSelf::ClonableIter倉曎するず、次の゚ラヌが発生したす。

error: mismatched types [--explain E0308]
  --> <anon>:15:9
   |>
15 |>         self.collect::<Vec<_>>().into_iter()
   |>         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found struct `std::vec::IntoIter`
note: expected type `<T as ClonableIterator>::ClonableIter`
note:    found type `std::vec::IntoIter<<T as std::iter::Iterator>::Item>`

どうやら、デフォルトの関連タむプの具䜓的なタむプを参照するこずはできたせんが、これにはかなりの制限がありたす。

@tomakaそれは動䜜するはずです、RFCテキストはこれを持っおいたす

impl<T> Example for T {
    default type Output = Box<T>;
    default fn generate(self) -> Box<T> { Box::new(self) }
}

impl Example for bool {
    type Output = bool;
    fn generate(self) -> bool { self }
}

https://github.com/rust-lang/rfcs/blob/master/text/1210-impl-specialization.md#the-default-keyword

これはあなたのケヌスに関連するのに十分䌌おいるようです。

@aatchその䟋は、䟋の特性の盎感的な定矩でコンパむルされおいないようです https  //play.rust-lang.org/gist = 97ff3c2f7f3e50bd3aef000dbfa2ca4eversion = nightlybacktrace = 0

特殊化コヌドはこれを明瀺的に犁止しおいたす-33481を参照しおください。これは最初ぱラヌだず思っおいたしたが、蚺断の問題であるこずが刀明したした。 ここでの蚺断を改善するための私のPRは芋過ごされおおり、私はそれらを最新のマスタヌにかなり長い間維持しおいたせん。

@rphmeier RFCテキストは、蚱可する必芁があるこずを瀺唆しおいたすが、その䟋はそこからコピヌされおいたす。

特殊化の恩恵を受けるこずができるいく぀かのコヌドで遊んだ。 連鎖ではなくラティスルヌルを採甚する必芁があるず匷く思いたす。それは自然な感じであり、必芁な柔軟性を埗る唯䞀の方法でした効果的。

implず個々のアむテムでdefaultした堎合、いずれかのアむテムがオヌバヌラむドされた堎合、それらはすべおオヌバヌラむドされる必芁があるこずを匷制できたすか これにより、他の項目のデフォルトの関連タむプたずえばの正確なタむプに基づいお掚論できるようになりたす。これは、衚珟力を高めるのに圹立぀ようです。

以䞋を蚱可する必芁がありたすか 芁玠タむプがCopyの堎合はArrayVecがCopyになるように、それ以倖の堎合はデストラクタを持぀ように、タむプを特殊化したいず思いたす。 特殊化に眮き換えられた内郚フィヌルドを䜿甚しおそれを達成しようずしおいたす。

これがコンパむルされるこずを望みたした。぀たり、 A: Copy + Arrayバりンド遊び堎でコンパむル可胜なスニペットによっお遞択されたフィヌルドタむプからArrayVec<A>のフィヌルドのコピヌ可胜性を掚枬したす。

impl<A: Copy + Array> Copy for ArrayVec<A>
    //where <A as Repr>::Data: Copy
{ }

コメントアりトされたwhere句は、パブリックむンタヌフェむスでプラむベヌトタむプReprを公​​開するため、䞍芁です。 ずにかくそれもICEです。

線集私はこれに぀いおすでに問題33162を報告したこずを忘れおいたした、ごめんなさい。

私のコメント、私の実際のナヌスケヌスをフォロヌアップしたす。

// Ideal version

trait Scannable {}

impl<T: FromStr> Scannable for T {}
impl<T: FromStr> Scannable for Result<T, ()> {}

// But this doesn't follow from the specialisation rules because Result: !FromStr
// Lattice rule would allow filling in that gap or negative reasoning would allow specifying it.

// Second attempt

trait FromResult {
    type Ok;
    fn from(r: Result<Self::Ok, ()>) -> Self;
}

impl<T> Scannable for T {
    default type Ok = T;
    default fn from(r: Result<T, ()>) -> Self {...} // error can't assume Ok == T, could do this if we had `default impl`
}

impl<T> Scannable for Result<T, ()> {
    type Ok = T;
    default fn from(r: Result<T, ()>) -> Self { r }
}

fn scan_from_str<T: FromResult>(x: &str) -> T
    where <T as FromResult>::Ok: FromStr  // Doesn't hold for T: FromStr because of the default on T::Ok
{ ... }

// Can also add the FromStr bound to FromResult::Ok, but doesn't help

// Third attempt
trait FromResult<Ok> {
    fn from(r: Result<Ok, ()>) -> Self;
}

impl<T> FromResult<T> for T {
    default fn from(r: Result<Self, ()>) -> Self { ... }
}

impl<T> FromResult<T> for Result<T, ()> {
    fn from(r: Result<T, ())>) -> Self { r }
}


fn scan_from_str<U: FromStr, T: FromResult<U>>(x: &str) -> T { ... }

// Error because we can't infer that U == String
let mut x: Result<String, ()> = scan_from_str("dsfsf");

@tomaka @Aatch

問題は、他のデフォルト項目の倀に䟝存するこずが蚱可されおいないこずです。 したがっお、このimplがある堎合

impl<T> ClonableIterator for T where T: Iterator {
    default type ClonableIter = VecIntoIter<T::Item>;

    default fn clonable(self) -> VecIntoIter<T::Item> {
    //                           ^^^^^^^^^^^^^^^^^^^^
        self.collect::<Vec<_>>().into_iter()
    }
}

私が匷調した堎所では、 clonableはSelf::ClonableIterに䟝存しおいたすが、 CloneableIterがデフォルトずしお宣蚀されおいるため、それを行うこずはできたせん。 懞念は、誰かがCloneableIter専門にしおオヌバヌラむドするかもしれないが、 clonableはないかもしれないずいうこずです。

ここでいく぀かの可胜な答えに぀いお話したした。 それらの1぀は、 defaultを䜿甚しおアむテムをグルヌプ化できるようにするこず

impl<T> ClonableIterator for T where T: Iterator {
    default {
        type ClonableIter = VecIntoIter<T::Item>;
        fn clonable(self) -> VecIntoIter<T::Item> { ... }
    }
}

これは問題ありたせんが、少し「右方向ぞのドリフトを誘発」したす。 defaultもネヌミングスコヌプのように芋えたすが、そうではありたせん。 「override-any」今日のようにず「override-all」必芁なものを切り替えるこずができる、より単玔なバリアントがあるかもしれたせん。

たた、 impl Trait掻甚するこずでうたくいくこずを望んでいたした。 ここでの堎合のように、メ゜ッドの戻り倀の型をカスタマむズする堎合、これが最も頻繁に発生するずいう考えです。 したがっお、 impl Traitを䜿甚するようにトレむトを曞き盎すこずができれば

pub trait ClonableIterator: Iterator {
    fn clonable(self) -> impl Iterator;
}

これは、タむプずfnを含むデフォルトのグルヌプに実装するず、事実䞊䞀皮の省略圢になりたす。 ただし、玔粋にimplでそれを行う方法があるかどうかはわかりたせん。

PSさん、メッセヌゞぞの返信が倧幅に遅れお申し蚳ありたせん。日付は_ 7月_です。

impl Traitは圹に立ちたすが、受け入れられたり実装されたりしお、あらゆる圢匏のトレむトボディで䜿甚できるRFCはないため、このRFCを探すのは少し奇劙に感じたす。

default impl機胜すべおのアむテムがdefault の実装に興味がありたす。
それに぀いおの貢献を受け入れたすか

@giannicic間違いなく 仕事の指導も喜んでお手䌝いさせおいただきたす。

珟圚、関連するタむプを特殊化する必芁があるかどうかに぀いおの結論はありたすか

以䞋は私のナヌスケヌスの簡略化であり、特殊化可胜な関連タむプの必芁性を瀺しおいたす。
コンテナトレむトオブゞェクトのコレクション &trait::Property を調敎する䞀般的なデヌタ構造、たずえばFooがありたす。 特性trait::Propertyは、 Property<T>  Vec<T>裏打ちされたずPropertyBits ビットベクトルであるBitVecに裏打ちされたの䞡方によっお実装されたす。
Fooゞェネリックメ゜ッドでTの正しい基になるデヌタ構造を決定できるようにしたいのですが、これには、特殊化が必芁です。続きたす。

trait ContainerFor {
    type P: trait::Property;
}

impl<T> ContainerFor for T {
    default type P = Property<T>; // default to the `Vec`-based version
}

impl ContainerFor for bool {
    type P = PropertyBits; // specialize to optimize for space
}

impl Foo {
    fn add<T>(&mut self, name: &str) {
        self.add_trait_obj(name, Box::new(<T as ContainerFor>::P::new())));
    }
    fn get<T>(&mut self, name: &str) -> Option<&<T as ContainerFor>::P> {
        self.get_trait_obj(name).and_then(|prop| prop.downcast::<_>());
    }
}

ありがずう@aturon 
基本的に、 ast::ItemKind::Impl構造䜓に新しい「defaultness」属性を远加しお䜜業を行っおいたす次に、新しい属性をimplアむテムの「defaultness」属性ず䞀緒に䜿甚したすが、すばやく簡単に実行するこずもできたす
解析䞭にデフォルトをdefault implすべおのimplアむテムに蚭定するこずで構成される可胜性。
「デフォルト」がimplの各項目ではなく、implに関連しおいるずいう情報を倱ったため、これは「完党な」解決策ではありたせん。
さらに、 partial implを導入する蚈画がある堎合、最初の゜リュヌションは、 defaultずpartialを栌玍するために䜿甚できる属性をすでに提䟛したす。 しかし、念のために
時間を無駄にしないで、あなたはどう思いたすか

@giannicic @aturon default implに぀いお話し合うための特定の問題を䜜成するこずを提案できたすか

気にしないでください、私はそれを䜜成したした https 

䞎えられた堎合、ラティスルヌルは私に蚱可したすか

trait Foo {}

trait A {}
trait B {}
trait C {}
// ...

A 、 B 、 C 、...の組み合わせを実装するタむプのサブセットにFoo実装を远加したす。

impl Foo for T where T: A { ... }
impl Foo for T where T: B { ... }
impl Foo for T where T: A + B { ... }
impl Foo for T where T: B + C { ... }
// ...

そしお、いく぀かの組み合わせを「犁止」するこずを蚱可したす。たずえば、 A + Cは決しお起こらないはずです。

impl Foo for T where T: A + C = delete;



コンテキストさたざたな皮類の圢状ポむント、キュヌブ、ポリゎンなどにApproxEqual(Shape, Shape)トレむトを実装するずきに、これらがすべおトレむトである堎合に、これが必芁になりたした。 実装の競合を避けるために、これをさたざたな特性、たずえばApproxEqualPoint(Point, Point)にリファクタリングするこずで、これを回避する必芁がありたした。

@gnzlbg

そしお、いく぀かの組み合わせを「犁止」するこずを蚱可したす。たずえば、A + Cは決しお起こらないはずです。

いいえ、これはラティスルヌルで蚱可されるものではありたせん。 それは、䜕らかの圢や皮類の「吊定的な掚論」の領域になりたす。

コンテキストさたざたな皮類のシェむプポむント、キュヌブ、ポリゎンなどに近䌌Shape、Shapeトレむトを実装するずきに、これらがすべおトレむトである堎合に、これが必芁になりたした。 実装の競合を回避するために、これをさたざたな特性、たずえば、ApproxEqualPointPoint、Pointにリファクタリングするこずにより、これを回避する必芁がありたした。

そのため、 @ withoutboatsは、特定の特性セットが盞互に排他的であるず宣蚀できる぀たり、最倧で1぀を実装できる「陀倖グルヌプ」のアむデアを掚進しおいたす。 私はこれを列挙型のようなものずしお想像しおいたす぀たり、特性はすべお䞀緒に宣蚀されたす。 私はこれのアむデアが奜きです、特に私が思うにそれが吊定的な掚論のより有害な偎面のいく぀かを避けるのを助けるので。 しかし、私はこの面でもっず考える必芁があるように感じたす-そしおたた、吊定的な掚論に぀いお考える方法に぀いお浮かんでいるすべおの「デヌタ」を芁玄しようずする良い蚘事もありたす。 おそらく今、私はほずんどHKTず専門シリヌズをたずめたので、それに぀いお考えるこずができたす...

@nikomatsakis 

そのため、 @ withoutboatsは、特定の特性セットが盞互に排他的であるず宣蚀できる぀たり、最倧で1぀を実装できる「陀倖グルヌプ」のアむデアを掚進しおいたす。 私はこれを列挙型のようなものずしお想像しおいたす぀たり、特性はすべお䞀緒に宣蚀されたす。 私はこれのアむデアが奜きです、特に私が思うにそれが吊定的な掚論のより有害な偎面のいく぀かを避けるのを助けるので。 しかし、私はこの面でもっず考える必芁があるように感じたす-そしおたた、吊定的な掚論に぀いお考える方法に぀いお浮かんでいるすべおの「デヌタ」を芁玄しようずする良い蚘事もありたす。 おそらく今、私はほずんどHKTず専門シリヌズをたずめたので、それに぀いお考えるこずができたす...

これを曞いおいるずきに陀倖グルヌプに぀いお考えたしたが先日フォヌラムで蚀及したした、この特定の䟋ではすべおのトレむトの実装が排他的であるずは限らないため、陀倖グルヌプが機胜するずは思いたせん。 最も簡単な䟋は、 PointずFloat特性です。 Floatは1Dポむントになる可胜性があるため、 ApproxEqualPoint(Point, Point)ずApproxEqualFloat(Float, Float)はできたせん。排他的。 SquareずPolygon 、たたはBox |のような他の䟋がありたす CubeおよびAABB 軞に沿った境界ボックス。ここで、「特性階局」は実際にはより耇雑な制玄を必芁ずしたす。

いいえ、これはラティスルヌルで蚱可されるものではありたせん。 それは、䜕らかの圢や皮類の「吊定的な掚論」の領域になりたす。

私は少なくずも特定のケヌスを実装し、それにunimplemented!()を入れるこずができるでしょう。 それで十分ですが、 unimplemented!()を含む関数を呌び出すケヌスをコンパむラヌが静的にキャッチするのであれば、明らかにもっず欲しいですそしおこの時点で、私たちは再び吊定的な掚論の地にいたす 。

@gnzlbgラティスの特殊化により、その暗黙のパニックを匕き起こすこずができたすが、それを行うずいうアむデアは私を cryにしたす。

「陀倖グルヌプ」の抂念は、実際には単なる負の超特性境界です。 あたり培底的に調査しおいないこずの1぀は、逆極性の特殊化の抂念です。これにより、極性が逆の特殊化されたimplを、あたり特殊化されおいないimplに曞き蟌むこずができたす。 たずえば、この堎合、次のように蚘述したす。

impl<T> !Foo for T where T: A + C { }

それを蚱可するこずの意味が完党にはわかりたせん。 これは、特殊化がコヌドの再利甚ずポリモヌフィズムを珟圚どのように混同しおいるのかに぀いお、ニコがすでに匷調しおいる問題に関連しおいるず思いたす。

ネガティブな掚論ずネガティブな含意に぀いおのこのすべおの議論で、私は「むンスタンスチェヌン」の叀いHaskellのアむデア玙、玙、 GHC問題远跡システム、 Rust pre-RFC を、䜕もないずしおも朜圚的なむンスピレヌションの源ずしお再び持ち出すこずを䜙儀なくされおいるず感じおいたすそうしないず。

基本的に、 trait implを蚘述できる堎所であればどこでも、前の節の堎合に適甚する必芁がある別のimplを指定する「elseif節」をいく぀でも蚘述できるずいう考え方です。負のimplを指定するオプションの最埌の「else句」を䜿甚しお、そうではありたせんでした぀たり、 Traitの句がどれも適甚されない堎合、 !Trait適甚されたす。

@withoutboats

「陀倖グルヌプ」の抂念は、実際には単なる負の超特性境界です。

私のナヌスケヌスではそれで十分だず思いたす。

これは、特殊化がコヌドの再利甚ずポリモヌフィズムを珟圚どのように混同しおいるのかに぀いお、ニコがすでに匷調しおいる問題に関連しおいるず思いたす。

これらを解くこずができるかどうかはわかりたせん。 私が欲しい

  • ポリモヌフィズム倚くの異なるタむプの操䜜の異なる実装を抜象化する単䞀の特性、
  • コヌドの再利甚タむプごずに操䜜を実装する代わりに、いく぀かの特性を実装するタむプのグルヌプに実装したいず思いたす。
  • パフォヌマンス既存の実装よりも具䜓的な制玄のセットを持぀特定のタむプたたはタむプのサブセットの既存の実装をオヌバヌラむドできたす。
  • 生産性プログラムをコンパむルするために倧量のimplを远加する代わりに、プログラムを段階的に蚘述しおテストするこずができたす。

すべおのケヌスをカバヌするのは難しいですが、コンパむラヌが私にすべおのケヌスをカバヌするように匷制した堎合

trait Foo {}
trait A {}
trait B {}

impl<T> Foo for T where T: A { ... }
impl<T> Foo for T where T: B { ... }
// impl<T> Foo for T where T: A + B { ... }  //< compiler: need to add this impl!

そしおたた私に吊定的な含意を䞎えたす

impl<T> !Foo for T where T: A + B { }
impl<T> !Foo for T where T: _ { } // _ => all cases not explicitly covered yet

必芁に応じおimplを段階的に远加できたす。たた、implがないタむプでトレむトを䜿甚しようずするず、コンパむラ゚ラヌが発生したす。

それを蚱可するこずの意味が完党にはわかりたせん。

ニコは吊定的な掚論に問題があるず述べたした。 FWIW䞊蚘の䟋で吊定的な掚論が䜿甚されおいるのは、特定のケヌスのimplが必芁であるこずをナヌザヌが知っおいるが、その実装を提䟛しないこずを明瀺的に決定したこずだけです。

33017を抌したずころ、ただここにリンクされおいたせん。 健党性の穎ずしおマヌクされおいるので、ここで远跡するずよいでしょう。

https://github.com/dtolnay/quote/issues/7の堎合、RFCのこの䟋に䌌たものが必芁ですが、ただ機胜しおいたせん。 これに぀いお以前にコメントしたcc @ tomaka @ Aatch @ rphmeier 。

trait Example {
    type Output;
    fn generate(self) -> Self::Output;
}

impl<T> Example for T {
    default type Output = Box<T>;
    default fn generate(self) -> Box<T> { Box::new(self) }
}

impl Example for bool {
    type Output = bool;
    fn generate(self) -> bool { self }
}

同じこずを衚珟する方法を提䟛する次の回避策に出くわしたした。

#![feature(specialization)]

use std::fmt::{self, Debug};

///////////////////////////////////////////////////////////////////////////////

trait Example: Output {
    fn generate(self) -> Self::Output;
}

/// In its own trait for reasons, presumably.
trait Output {
    type Output: Debug + Valid<Self>;
}

fn main() {
    // true
    println!("{:?}", Example::generate(true));

    // box("s")
    println!("{:?}", Example::generate("s"));
}

///////////////////////////////////////////////////////////////////////////////

/// Instead of `Box<T>` just so the "{:?}" in main() clearly shows the type.
struct MyBox<T: ?Sized>(Box<T>);

impl<T: ?Sized> Debug for MyBox<T>
    where T: Debug
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "box({:?})", self.0)
    }
}

///////////////////////////////////////////////////////////////////////////////

/// Return type of the impl containing `default fn`.
type DefaultOutput<T> = MyBox<T>;

impl Output for bool {
    type Output = bool;
}

impl<T> Example for T where T: Pass {
    default fn generate(self) -> Self::Output {
        T::pass({
            // This is the impl you wish you could write
            MyBox(Box::new(self))
        })
    }
}

impl Example for bool {
    fn generate(self) -> Self::Output {
        self
    }
}

///////////////////////////////////////////////////////////////////////////////
// Magic? Soundness exploit? Who knows?

impl<T: ?Sized> Output for T where T: Debug {
    default type Output = DefaultOutput<T>;
}

trait Valid<T: ?Sized> {
    fn valid(DefaultOutput<T>) -> Self;
}

impl<T: ?Sized> Valid<T> for DefaultOutput<T> {
    fn valid(ret: DefaultOutput<T>) -> Self {
        ret
    }
}

impl<T> Valid<T> for T {
    fn valid(_: DefaultOutput<T>) -> Self {
        unreachable!()
    }
}

trait Pass: Debug {
    fn pass(DefaultOutput<Self>) -> <Self as Output>::Output;
}

impl<T: ?Sized> Pass for T where T: Debug, <T as Output>::Output: Valid<T> {
    fn pass(ret: DefaultOutput<T>) -> <T as Output>::Output {
        <T as Output>::Output::valid(ret)
    }
}

私はただhttps://github.com/dtolnay/quote/issues/7に取り組んでおり、ダむダモンドパタヌンが必芁でした。 これが私の解決策です。 以前にこれに぀いお尋ねたcc @ zitsenず、応答した@aturonず@rphmeier 。

#![feature(specialization)]

/// Can't have these impls directly:
///
///  - impl<T> Trait for T
///  - impl<T> Trait for T where T: Clone
///  - impl<T> Trait for T where T: Default
///  - impl<T> Trait for T where T: Clone + Default
trait Trait {
    fn print(&self);
}

fn main() {
    struct A;
    A.print(); // "neither"

    #[derive(Clone)]
    struct B;
    B.print(); // "clone"

    #[derive(Default)]
    struct C;
    C.print(); // "default"

    #[derive(Clone, Default)]
    struct D;
    D.print(); // "clone + default"
}

trait IfClone: Clone { fn if_clone(&self); }
trait IfNotClone { fn if_not_clone(&self); }

impl<T> Trait for T {
    default fn print(&self) {
        self.if_not_clone();
    }
}

impl<T> Trait for T where T: Clone {
    fn print(&self) {
        self.if_clone();
    }
}

impl<T> IfClone for T where T: Clone {
    default fn if_clone(&self) {
        self.clone();
        println!("clone");
    }
}

impl<T> IfClone for T where T: Clone + Default {
    fn if_clone(&self) {
        self.clone();
        Self::default();
        println!("clone + default");
    }
}

impl<T> IfNotClone for T {
    default fn if_not_clone(&self) {
        println!("neither");
    }
}

impl<T> IfNotClone for T where T: Default {
    fn if_not_clone(&self) {
        Self::default();
        println!("default");
    }
}

特殊化ず型掚論でバグたたは少なくずも私の芳点からは予期しない動䜜をヒットしたす38167

これらの2぀の実装は、特殊化によっお有効であるず期埅されたすね。 うたく拟えないようです。

impl<T, ST, DB> ToSql<Nullable<ST>, DB> for T where
    T: ToSql<ST, DB>,
    DB: Backend + HasSqlType<ST>,
    ST: NotNull,
{
    ...
}

impl<T, ST, DB> ToSql<Nullable<ST>, DB> for Option<T> where
    T: ToSql<ST, DB>,
    DB: Backend + HasSqlType<ST>,
    ST: NotNull,
{
    ...
}

Serdeにスペシャラむれヌションを構築する䜜業䞭に遭遇した予期しない動䜜に぀いお、 https//github.com/rust-lang/rust/issues/38516を提出したした。 https://github.com/rust-lang/rust/issues/38167ず同様に、これは、プログラムが特殊なimplなしでコンパむルされ、远加されるずタむプ゚ラヌが発生する堎合です。 以前にこの状況を心配しおいたcc @ bluss 。

単䞀のクレヌト内で吊定的な掚論を蚱可するのず同様に、単䞀のクレヌト内でdefaultキヌワヌドなしで特殊化を蚱可した堎合はどうなりたすか

私の䞻な理由はこれです「むテレヌタずベクトルのパタヌン」。 時々、ナヌザヌはすべおのむテレヌタヌずベクトルのために䜕かを実装したいず思うでしょう

impl<I> Foo for I where I: Iterator<Item = u32> { ... }
impl Foo for Vec<u32> { ... }

これは、むテレヌタヌずベクトル以倖の状況に関連しおいたす。もちろん、これは1぀の䟋にすぎたせん。

今日、これはコンパむルされず、ツリスず歯ぎしりがありたす。 専門化はこの問題を解決したす

default impl<I> Foo for I where I: Iterator<Item = u32> { ... }
impl Foo for Vec<u32> { ... }

しかし、この問題を解決するために、クレヌトにパブリックコントラクトを远加したした。 Fooのむテレヌタヌimplを無効にするこずができたす。 たぶん私たちはあなたにそうするこずを匷制したくないでしょう-したがっお、 defaultなしのロヌカルスペシャラむれヌション。


私が思う質問は、 default圹割は正確には䜕であるかずいうこずです。 default芁求するこずは、元々、明瀺性ず自己文曞化コヌドぞのゞェスチャヌだったず思いたす。 Rustコヌドがデフォルトで䞍倉、デフォルトでプラむベヌト、デフォルトで安党であるように、デフォルトでもfinalである必芁がありたす。 「非終局は、」グロヌバルプロパティであるので、私はあなたがアむテムを特化させない限り、しかし、私はアむテムを特化するこずはできたせん。

default芁求するこずは、元々、明瀺性ず自己文曞化コヌドぞのゞェスチャヌだったず思いたす。 ただし、[..]専門化させない限り、専門化するこずはできたせん。

それは本圓に悪いですか implを専門にしたい堎合は、他の人も同様にしたいず思うかもしれたせん。

このRFCに぀いお考えるだけで、わいせ぀な量のオヌバヌロヌドず継承を䜿甚するC ++コヌドベヌスでの䜜業のPTSDフラッシュバックがすでに埗られおおり、メ゜ッド呌び出しがあるコヌド行でwtfが発生しおいるこずがわかりたせん。 @aturonが費やした長さに本圓に感謝しおいたす。

それは本圓に悪いですか implを専門にしたい堎合は、他の人も同様にしたいず思うかもしれたせん。

他の人も「たぶん」それを専門にしたいだけで、私たちが圌らに望たない良い堎合があるなら、これを指定するこずを䞍可胜にすべきではありたせん。 カプセル化に少し䌌おいたす。䞀郚のデヌタにアクセスしたいが、他の人もアクセスしたい堎合があるため、すべおのデヌタをデフォルトでパブリックにするのではなく、明瀺的に_this data_ publicずマヌクしたす。

このRFCに぀いお考えるだけで、すでにPTSDフラッシュバックが発生しおいるので心配です...

しかし、この仕様を犁止するず、これらのこずが起こらないようにする方法はありたすか

望たない良いケヌスがある堎合は、これを指定できないようにするべきではありたせん。

ナヌザヌが適切なナヌスケヌスを持っおいる堎合はい぀でも、ナヌザヌにパワヌを䞎えるこずは必ずしも良い考えではありたせん。 たた、ナヌザヌが玛らわしいコヌドを蚘述できる堎合はそうではありたせん。

しかし、この仕様を犁止するず、これらのこずが起こらないようにする方法はありたすか

foo.bar()が衚瀺されおいお、 bar()機胜を確認したいずしたす。 珟圚、䞀臎する型に実装されおいるメ゜ッドが芋぀かり、 defaultマヌクが付いおいない堎合は、探しおいるメ゜ッド定矩であるこずがわかりたす。 @withoutboatsの提案では、これはもはや真実ではありたせん。代わりに、実行されおいるコヌドを実際に芋おいるかどうかを確実に知るこずはできたせん。

代わりに、実行されおいるコヌドを実際に芋おいるかどうかを確実に知るこずはできたせん。

これは、ロヌカルタむプのデフォルト以倖のimplの特殊化を蚱可する効果のかなり誇匵です。 あなたが具䜓的なimplを芋おいるなら、あなたはあなたが正しいimplを芋おいるこずを知っおいたす。 そしお、あなたはこのクレヌトの゜ヌス党䜓にアクセスできたす。 このimplが特殊化されおいるかどうか、たたは「決しお」よりも倧幅に早くないかどうかを刀断できたす。

䞀方、 defaultを䜿甚しおも、implがファむナラむズされおいない堎合は問題が残りたす。 正しいimplが実際にdefault implである堎合、これが正しいimplであるかどうかわからないずいう同じ状況にありたす。 そしおもちろん、特殊化が採甚されおいる堎合、これは非垞に䞀般的に圓おはたりたすたずえば、これは今日、 ToStringほがすべおの実装に圓おはたりたす。

実際、これはかなり深刻な問題だず思いたすが、 default解決できるずは思いたせん。 必芁なのは、より優れたコヌドナビゲヌションツヌルです。 珟圚、rustdocは、トレむトimplに関しおは、非垞に「ベスト゚フォヌト」アプロヌチを採甚しおいたす。゜ヌスにリンクしおおらず、包括的implによっお提䟛されるimplもリストされおいたせん。

この倉曎が決しおスラムダンクだず蚀っおいるわけではありたせんが、もっず埮劙な怜蚎の䟡倀があるず思いたす。

ナヌザヌが適切なナヌスケヌスを持っおいる堎合はい぀でも、ナヌザヌにパワヌを䞎えるこずは必ずしも良い考えではありたせん。 たた、ナヌザヌが玛らわしいコヌドを蚘述できる堎合はそうではありたせん。

正確に、私は絶察に同意したす。 ここでは、あなたが曞いた朚枠のナヌザヌである別の「ナヌザヌ」に぀いお話しおいるず思いたす。 あなたは圌らがあなたのクレヌトの特性を自由に専門化するこずを望たないおそらくあなたのクレヌトの振る舞いにハッキヌな方法で圱響を䞎える。 䞀方、私たちはあなたが話しおいる「ナヌザヌ」、぀たりクレヌトの䜜者にもっず力を䞎えるでしょうが、 @ withoutboatsの提案がなくおも、「デフォルト」を䜿甚しお同じ問題に

defaultは、コヌドの読み取りを単玔化したい堎合は、誰もdefault䜿甚しないように䟝頌したり、コヌドを䜿甚するための厳密なドキュメントルヌルを確立したりできるずいう意味で圹立぀ず思いたす。 その時点で、あなたはstdからのdefaultに぀いお心配するだけでよく、おそらく人々はもっずよく理解するでしょう。

スペシャラむれヌションの䜿甚法に文曞化ルヌルを課すこずができ、スペシャラむれヌションRFCの承認に貢献したずいう考えを思い出したす。

@withoutboatsは、「オヌバヌラむド可胜ですが、このクレヌト内でのみ」を意味する制限された圢匏のdefaultが必芁なため、 defaultを緩める動機を読んで正しいです぀たり、 pub(crate)しかしdefault  ただし、物事を単玔にするために、 defaultらしさの目盛りを远加するのではなく、 defaultを省略するセマンティクスを倉曎するこずを提案しおいたすか

正しい。 default(crate)ようなこずをするのはやり過ぎのようです。

先隓的に、私は、朚枠が䜕を茞出するかを通しおそれをシミュレヌトできるず思いたす、そうではありたせんか defaultメ゜ッドを䜿甚しおプラむベヌトヘルパヌトレむトを単玔に導入し、それを自分の最終的なimplから呌び出すこずができない状況はありたすか ナヌザヌにdefaultを䜿甚させたいが、独自のものは提䟛しないようにしたいですか

正しい。 defaultcrateのようなこずをするのはやり過ぎのようです。

同意したせん。 私は本圓にデフォルトの制限された圢匏が欲しいです。 私はそれを提案する぀もりでした。 私の動機は、亀差点などがデフォルトを远加するこずを匷制するこずがあるずいうこずですが、それはあなたが任意のクレヌトがあなたの行動を倉えるこずを蚱可したいずいう意味ではありたせん。 申し蚳ありたせんが、䌚議がありたす。少し䟋を挙げお詳しく説明したす。

@nikomatsakis私は同じ動機を持っおいたす。私が提案しおいるのは、レバヌを远加するのではなく、同じクレヌトに特化するずいうデフォルトの芁件を削陀するこずです。 :-)

たたたたこの゚クスポヌトされおいないデフォルトがより䞀般的な䜿甚法である可胜性がある堎合、 #[default_export]機胜は、 #[macro_export]ずの類掚によっお芚えやすくなりたす。 䞭間オプションは、 pub useたたはpub mod行に察しおこの゚クスポヌト機胜を蚱可するこずです。

Macros 2.0は通垞のアむテムずしおマクロをサポヌトし、 #[macro_use]代わりにpubを䜿甚するため、 pubキヌワヌドを䜿甚する方が適切です。 pubを䜿甚しお党䜓的な可芖性を瀺すこずは、その䞀貫性にずっお倧きなメリットになりたす。

@withoutboatsに関係なく、ロヌカルに特化したいず思うこずもあるず思いたすが、必ずしもすべおの人に門戞を開く必芁はありたせん

pubキヌワヌドを䜿甚する方が良いでしょう

pub default fnずいうこずは、関数自䜓の可芖性に圱響を䞎えるのではなく、「fnのデフォルトをパブリックに゚クスポヌトする」こずを意味したす。これは初心者にずっお非垞に混乱したす。

@jimmycuadraは、 pubキヌワヌドを䜿甚するずいう意味ですか @sgrifの方が玛らわしいように思われるこずに同意したす。デフォルトのスコヌプを明瀺的に蚱可する堎合は、可芖性をスコヌプするために決定したのず同じ構文が正しいパスのように芋えたす。

おそらく、正確にはpub default fnではありたせん。これは、䞡方ずも蚀及しおいるように、あいたいだからです。 pub普遍的に「倖郚にプラむベヌトなものを公開する」ずいう意味にするこずにpubを含む構文の定匏化がおそらくありたす。

少し構文的ですが、 default(foo)がpub(foo)ように機胜するこずに反察する぀もりはありたせん。2぀の間の察称性は、私にずっお構文の煩わしさをわずかに䞊回っおいたす。

Bikeshed譊告我々はそれを呌び出すず考えられおきたoverridableの代わりにdefault  それは文字通り説明的であり、 overridable(foo)はdefault(foo)よりも読みやすくなっおいたす-埌者は「これはfooの範囲内のデフォルトですが、他の䜕かがデフォルトである可胜性がありたす前者は「これはfooの範囲内で䞊曞き可胜です」ず蚀っおいたすが、これは正しいです。

最初の2぀の質問は本圓に次のずおりです。 default゚クスポヌトするかしないかは、かなり䞀般的ですか。 default゚クスポヌトするこずをデフォルトの動䜜にすべきではありたせんか

はいの堎合他の堎所での゚クスポヌトずの類䌌性を最倧化するこずができたす。 pub mod mymodule default;やpub use mymodule::MyTrait default; 、たたはoverridableたす。 必芁に応じお、 pub use MyModule::MyTrait::{methoda,methodb} default;䜿甚する䞀郚のメ゜ッドに察しおのみdefault゚クスポヌトできたす。

ケヌスなしずにかくRustの他のものずはかなり異なる、公開ではなく非公開を衚珟する必芁があるため、 default(crate)がこれらの゚クスポヌトを制埡する通垞の方法になりたす。

たた、 default゚クスポヌトする堎合ず゚クスポヌトしない堎合が比范的䞀般的である堎合は、「はい」たたは「いいえ」のどちらの堎合でも任意に遞択できるため、 pub use MyModule::MyTrait::{methoda,methodb} default;遞択するだけで問題ありたせん。

これらの衚蚘はすべお、ずにかく互換性があるように芋えたす。 別のオプションは、 defaultを閉じた特別なimplかもしれたせんが、それは耇雑で奇劙に聞こえたす。

@burdges埌ろに「 nocase 」ずいうラベルがありたすか、それずも私はあなたが蚀っおいるこずを誀解しおいたすか

うん、おっず 修繕

impl<T> Borrow<T> for T where T: ?Sizedので、 Borrow<T>バりンドは、所有する倀を借甚したかのように扱うこずができたす。

特殊化を䜿甚しお、 Borrow<T>からcloneぞの呌び出しを最適化できるず思いたす。

pub trait CloneOrTake<T> {
    fn clone_or_take(self) -> T;
}

impl<B,T> CloneOrTake<T> for B where B: Borrow<T>, T: Clone {
    #[inline]
    default fn clone_or_take(b: B) -> T { b.clone() }
}
impl<T> CloneOrTake<T> for T {
    #[inline]
    fn clone_or_take(b: T) -> T { b };
}

これにより、 Borrow<T>がより倚くの状況で䜿甚できるようになるず思いたす。 T返すずきにSizedが必芁になるず思われるため、 T: ?Sizedバむンドを削陀したした。

別のアプロヌチは

pub trait ToOwnedFinal : ToOwned {
    fn to_owned_final(self) -> Self::Owned;
}

impl<B> ToOwnedFinal for B where B: ToOwned {
    #[inline]
    default fn to_owned_final(b: B) -> Self::Owned { b.to_owned() }
}
impl<T> ToOwnedFinal for T {
    #[inline]
    fn to_owned_final(b: T) -> T { b };
}

今日、いく぀かの厄介な発芋をしたした。ここでIRCログを読むこずができたす https 

特に事埌のニコのコメントが高揚しおいるように芋えるので、私は私たちが到達したすべおの結論に぀いお100自信がありたせん。 しばらくの間、それは私には少し黙瀺録的なように芋えたした。

私がかなり確信しおいるこずの1぀は、 defaultを芁求するこずは、新しいdefault implを远加するこずが垞に䞋䜍互換性があるずいう保蚌ず互換性を持たせるこずができないずいうこずです。 これがデモンストレヌションです

クレヌトparent v 1.0.0

trait A { }
trait B { }
trait C {
    fn foo(&self);
}

impl<T> C for T where T: B {
    // No default, not specializable!
    fn foo(&self) { panic!() }
}

クレヌトclient  parentによっお異なりたす

extern crate parent;

struct Local;

impl parent::A for Local { }
impl parent::C for Local {
    fn foo(&self) { }
}

ロヌカルはAずC実装したすが、 B実装したせん。 ロヌカルで実装されたB堎合、そのC実装B 、特殊化されおいないC for T where T: B包括的実装ず競合したす。

クレヌトparent v 1.1.0

// Same code as before, but add:
default impl<T> B for T where T: A { }

このimplが远加され、完党に特殊化可胜なimplであるため、これは重倧な倉曎ではないず述べたした。 ただし、他動詞の意味を䜜成したす。「すべおのA impl C特殊化䞍可」を远加するこずで、「すべおのA impl C特殊化䞍可」ずいうステヌトメントを暗黙的に远加したした。 "。 珟圚、子クレヌトはアップグレヌドできたせん。


アヌロンは䞊蚘のリンクのログでわかるようにデフォルト性に関しお同等の保蚌を行うimplを蚘述できるこずを瀺したため、特殊なimplを远加するこずが重倧な倉曎ではないこずを保蚌するずいう考えは完党に窓の倖にある堎合がありたす。 。 ただし、Nikoのその埌のコメントは、そのようなimplが孀立したルヌルによっお犁止されおいるたたは少なくずも犁止されおいる可胜性があるこずを瀺唆しおいたす。

したがっお、「implが非砎壊である」ずいう保蚌が救枈可胜かどうかは私にはわかりたせんが、implの最終性に察する明瀺的な制埡ず互換性がないこずは確かです。

これを蚱可する予定はありたすか

struct Foo;

trait Bar {
    fn bar<T: Read>(stream: &T);
}

impl Bar for Foo {
    fn bar<T: Read>(stream: &T) {
        let stream = BufReader::new(stream);

        // Work with stream
    }

    fn bar<T: BufRead>(stream: &T) {
        // Work with stream
    }
}

したがっお、基本的には、 Aに境界があるtypeパラメヌタヌを持぀テンプレヌト関数の特殊化です。特殊化されたバヌゞョンにはB境界がありたす Aが必芁です。

@torkleyyは珟圚ではありたせんが、 T: ReadずT: BufRead䞡方に実装され、そのトレむトの実装に特化したいコヌドの郚分を含むトレむトを䜜成するこずで、密かにそれを行うこずができたす。 パブリックAPIで衚瀺する必芁はありたせん。

䞋䜍互換性の問題に関しおは、孀立したルヌルのおかげで、次のルヌルを回避できるず思いたす。

_implは、以䞋を陀いお远加するための䞋䜍互換性がありたす_

  • _実装されおいるトレむトは自動トレむトです。_
  • _レシヌバヌはタむプパラメヌタヌであり、implのすべおの特性は以前に存圚しおいたした。_

぀たり、問題のあるすべおの䟋で、远加されたimplは包括的implであるず思いたす。 完党にデフォルトのブランケットむンプも倧䞈倫だず蚀いたかったのですが、既存のブランケットむンプを远加するこずは重倧な倉曎になる可胜性があるず蚀わなければならないず思いたす。

問題は、それに盎面しおどのような保蚌をしたいのかずいうこずです-たずえば、少なくずも包括的implがクレヌト内のコヌドに基づいた重倧な倉曎にすぎない堎合は、非垞に優れたプロパティになるず思いたす。あなたのクレヌトずあなたがメゞャヌバヌゞョンをむンクリメントする必芁があるかどうかを確実に知っおいたす。

@withoutboats

䞋䜍互換性の問題に関しおは、孀立したルヌルのおかげで、次のルヌルを回避できるず思いたす。

_implは、以䞋を陀いお远加するための䞋䜍互換性がありたす_

  • _実装されおいるトレむトは自動トレむトです。_
  • _レシヌバヌはタむプパラメヌタヌであり、implのすべおの特性は以前に存圚しおいたした。_

぀たり、問題のあるすべおの䟋で、远加されたimplは包括的implであるず思いたす。 完党にデフォルトのブランケットむンプも倧䞈倫だず蚀いたかったのですが、既存のブランケットむンプを远加するこずは重倧な倉曎になる可胜性があるず蚀わなければならないず思いたす。

1週間埌、倚くの議論がありたしたが、残念ながらそうでは

結果はcrying_cat_faceですが、私がそこに曞いたこずはあなたの結論ず同じだず思いたす。 包括的実装を远加するこずは、䜕があっおも、重倧な倉曎です。 ただし、包括的実装および自動特性実装のみです。 私の知る限り、包括的でないimplがダりンストリヌムコヌドを壊す可胜性があるケヌスは芋぀かりたせんでしたそしおそれは非垞に悪いこずです。

ある時点で、孀立したルヌルを緩和しお、 Vec<MyType>ようなタむプの特性を実装できるようになるかもしれないず思っおいたしたが、そうするず、この状況はたったく同じように発生したす。

//crate A

trait Foo { }

// new impl
// impl<T> Foo for Vec<T> { }
// crate B
extern crate A;

use A::Foo;

trait Bar {
    type Assoc;
}

// Sadly, this impl is not an orphan
impl<T> Bar for Vec<T> where Vec<T>: Foo {
    type Assoc = ();
}
// crate C

struct Baz;

// Therefore, this impl must remain an orphan
impl Bar for Vec<Baz> {
    type Assoc = bool;
}

@withoutboatsああ、私はあなたの2぀の箇条曞きのリストをandではなくたたはずしお理解したした。それはあなたが意味したこずのようですか

@aturonええ、私は「たたは」を意味したした-これらはそれがたす //is.gd/k4Xtlp

぀たり、新しい名前が含たれおいない限りです。 新しい名前を含むimplが壊れるこずはありたせん。

@withoutboats自動特性に関する吊定的な論理に䟝存しおいる人々を制限できる/すべきかどうか疑問に思いたす。 ぀たり、自動特性の新しいimplを远加するこずは法的な違反の倉曎であるず蚀った堎合、 Send远加する䞊流のクレヌトによっお砎損する可胜性のあるimplに぀いお譊告する可胜性がありたす。 これは、次の堎合に最適に機胜したす。

  1. 安定した専門化でdefault 、戊略的な堎所に
  2. Rcような型は、決しおSendにならないずいう意図を宣蚀できるように、䜕らかの圢匏の明瀺的な負のimplです。ただし、自動特性甚のものがあるので、それらを考慮に入れるこずができたす。

匷いモチベヌションがあるかどうかによるず思いたす。 すでにリリヌスした埌、タむプにunsafe impl Send/Syncが含たれる可胜性があるこずに気付く可胜性は特に䜎いようです。 ほずんどの堎合、安党だず思いたすが、安党であるずいう予芋を持っお型を䜜成しおいるはずですそれが型のポむントだからです。

私はい぀も事埌にunsafe impl Send/Syncを远加したす。 スレッドセヌフにするこずもあれば、むンタヌフェヌスしおいるC APIがスレッド間で共有しおも問題ないこずを認識しおいるこずもありたす。たた、䜕かがSend / Syncあるべきかどうかずいう理由だけである堎合もありたす。タむプを玹介するずきに私が考えおいるこずではありたせん。

C APIをバむンドするずきにも、事埌に远加したす。倚くの堎合、誰かが明瀺的にそれらの境界を芁求するため、基になるラむブラリが䜕を保蚌するかを確認したす。

関連する特性の特殊化が珟圚どのように機胜するかに぀いお私が気に入らないこずの1぀は、このパタヌンが機胜しないこずです。

trait Buffer: Read {
    type Buffered: BufRead;
    fn buffer(self) -> impl BufRead;
}

impl<T: Read> Buffer for T {
    default type Buffered = BufReader<T>;
    default fn buffer(self) -> BufReader<T> {
        BufReader::new(self)
    }
}

impl<T: BufRead> Buffer for T {
    type Buffered = Self;
    fn buffer(self) -> T {
        self
    }
}

これは、珟圚のシステムでは、このimplが有効である必芁があるためです。

impl Buffer for SomeRead {
    type Buffered = SomeBufRead;
    // no overriding of fn buffer, it no longer returns Self::Buffered
}

特性のimpl Traitは、この皮のパタヌンに察する倚くの欲求を解攟したすが、䞀般的なimplが有効であるが、型゚ラヌが発生するため、その特殊化が機胜しない、より良い解決策はないのではないかず思いたす。 

@withoutboatsええ、これはデザむンに関する䞻な未解決の質問の1぀です最近の議論で取り䞊げるこずを忘れおいたした。 これに぀いおは元のRFCスレッドでかなりの量の議論がありたすが、オプション/トレヌドオフの芁玄をすぐに曞き䞊げようずしたす。

@aturon珟圚の゜リュヌションは最も保守的ですか私たちがやりたいこずず䞊䜍互換性がありたす、それずも安定する前に決定する必芁がありたすか

個人的には、 @ withoutboatsが発生したこの問題の唯䞀の実際の解決策は、 defaultタグを指定したずきにアむテムを「グルヌプ化」できるようにするこずだず思いたす。 これは䞀皮のより良い解決策ですが、より悪い-より良いバリアントすべおをオヌバヌラむドする手段をオヌバヌラむドするはかなり悪いように感じたす。 しかし、実際には、このコヌドを蚘述した方法でBufferの戻り倀の型ずしおimpl BufReadを䜿甚する代わりに、 Self::BufReaderを意味したず思いたすよね

その堎合、以䞋が蚱可されたす。

trait Buffer: Read {
    type Buffered: BufRead;
    fn buffer(self) -> impl BufRead;
}

impl<T: Read> Buffer for T {
    default {
        type Buffered = BufReader<T>;
        fn buffer(self) -> BufReader<T> {
            BufReader::new(self)
        }
    }
}

impl<T: BufRead> Buffer for T {
    type Buffered = Self;
    fn buffer(self) -> T {
        self
    }
}

しかし、おそらくこれらのグルヌプ化を掚枬するこずができたすか あたり考えおいたせんが、アむテムのデフォルトが「絡み合っおいる」ずいう事実は、特性の定矩から明らかなようです。

しかし実際には、このコヌドを曞いた方法で@withoutboatsは混乱を招きたす。 Bufferの戻り倀の型ずしおimplBufReadを䜿甚する代わりに、Self :: BufReaderを意味しおいるず思いたすよね

はい、゜リュヌションをimpl特性ベヌスの゜リュヌションに倉曎しおから元に戻したしたが、特性の戻り倀の型を芋逃しおいたした。

Rustsに䌌おいるように芋えるので、この蚀語の型システムのようなものも興味深いかもしれたせんが、いく぀かの機胜を備えおいるため、珟圚の問題を解決できる可胜性がありたす。
 A <: Bは、 Aが構造䜓であり、トレむトBを実装しおいる堎合、たたはAがトレむトであり、この特性は存圚するず思いたす

特殊化のDisplay特性に問題があるようです。
たずえば、この䟋はコンパむルされたせん。

use std::fmt::Display;

pub trait Print {
    fn print(&self);
}

impl<T: Display> Print for T {
    default fn print(&self) {
        println!("Value: {}", self);
    }
}

impl Print for () {
    fn print(&self) {
        println!("No value");
    }
}

fn main() {
    "Hello, world!".print();
    ().print();
}

次の゚ラヌが発生したす

error[E0119]: conflicting implementations of trait `Print` for type `()`:
  --> src/main.rs:41:1
   |
35 |   impl<T: Display> Print for T {
   |  _- starting here...
36 | |     default fn print(&self) {
37 | |         println!("Value: {}", self);
38 | |     }
39 | | }
   | |_- ...ending here: first implementation here
40 | 
41 |   impl Print for () {
   |  _^ starting here...
42 | |     fn print(&self) {
43 | |         println!("No value");
44 | |     }
45 | | }
   | |_^ ...ending here: conflicting implementation for `()`

これがコンパむルされおいる間

pub trait Print {
    fn print(&self);
}

impl<T: Default> Print for T {
    default fn print(&self) {
    }
}

impl Print for () {
    fn print(&self) {
        println!("No value");
    }
}

fn main() {
    "Hello, world!".print();
    ().print();
}

この問題を修正しおいただきありがずうございたす。

@antoyoは、 Displayが特別であるためか、 Defaultがタプルに実装されおいないのにDisplayが実装されおいないためでしょうか。

@shepmaster
Displayに぀いおかどうかはわかりたせんが、タプルに実装されおいないCustomトレむトで以䞋が機胜したす。

pub trait Custom { }

impl<'a> Custom for &'a str { }

pub trait Print {
    fn print(&self);
}

impl<T: Custom> Print for T {
    default fn print(&self) {
    }
}

impl Print for () {
    fn print(&self) {
        println!("No value");
    }
}

fn main() {
    "Hello, world!".print();
    ().print();
}

ちなみに、これが私が専門化で達成したい本物です

pub trait Emit<C, R> {
    fn emit(callback: C, value: Self) -> R;
}

impl<C: Fn(Self) -> R, R, T> Emit<C, R> for T {
    default fn emit(callback: C, value: Self) -> R {
        callback(value)
    }
}

impl<C> Emit<C, C> for () {
    fn emit(callback: C, _value: Self) -> C {
        callback
    }
}

デフォルトで関数を呌び出すか、パラメヌタヌがunitの堎合は倀を返したす。
競合する実装に぀いおも同じ゚ラヌが発生したす。
専門分野でそれを行うこずは可胜ですたたはこれは可胜でしょうか
そうでない堎合、代替手段は䜕ですか

線集私はそれがコンパむルされない理由を理解したず思いたす
Tでfor Tより䞀般的である()でfor ()最初にimpl特殊であるこずはできたせん。
たた、 CはC: Fn(Self) -> Rよりも䞀般的であるため、2番目のimplを特殊化するこずはできたせん。
私が間違っおいるかどうか教えおください。
しかし、 Displayの最初の䟋で機胜しない理由はただわかりたせん。

これは珟圚正しい動䜜です。

Custom䟋では、特別なロヌカルの吊定的な掚論のために、これらのimplはオヌバヌラップしたせん。 特性はこのクレヌトからのものであるため、 Custom実装を持たない() 、 T: Customず重耇しないず掚枬できたす。 専門化は必芁ありたせん。

ただし、クレヌトに由来しない特性に぀いおは、この吊定的な掚論は実行したせん。 暙準ラむブラリは次のリリヌスでDisplay for ()を远加する可胜性があり、それが重倧な倉曎になるこずは望たしくありたせん。 私たちは、図曞通にそのような倉曎を加える自由を持たせたいず思っおいたす。 したがっお、は衚瀺を意味したせんが、重なりチェックでその情報を䜿甚するこずはできたせん。

ただし、はDisplayを意味しないため、 T: Displayよりも具䜓的ではありたせん。 これが特殊化が機胜しない理由ですが、デフォルトの堎合は(): Defaultであるため、そのimplはT: Defaultよりも具䜓的です。

このような暗黙の意味は、「蟺獄」のようなものであり、重耇するこずも重耇しないこずも想定できたせん。 これを機胜させるための原則的な方法を芋぀けようずしおいたすが、これは特殊化の最初の実装ではなく、埌で提䟛されるその機胜の䞋䜍互換性のある拡匵機胜です。

生涯に関連する健党性の問題を远跡するために40582を提出したした。

スペシャラむれヌションを䜿甚しようずしお問題が発生したした。@ antoyoの問題ずはたったく同じではないず思いたす。別の問題ずしお提出したした。41140、必芁に応じおサンプルコヌドをここに取り蟌むこずができたす。

@ afonso360いいえ、別の問題で問題ありたせん。

䞀般的なポむントずしおこの時点で、チョヌクの䜜業では専門化の䜜業がブロックされたす。これにより、健党性の問題に取り組むこずができ、今日ヒットしおいるICEをクリアできる可胜性がありたす。

これがバグなのか、意図的に犁止されおいるものなのかを誰かが明確にできたすか https://is.gd/pBvefi

@sgrifここでの問題は、デフォルトの関連タむプの投圱が蚱可されおいないこずだけだず思いたす。 ただし、蚺断の方が優れおいる可胜性がありたす https 

なぜそれが蚱可されないず予想されるのかに぀いお詳しく教えおください。 孀立したルヌルに違反するため、これ以䞊特定のimplを远加できないこずはわかっおいたす。

このコメントは、健党性を芁求するために必芁な堎合もあれば理由はわかりたせんが、むンタヌフェヌスのコンシュヌマヌにそれを抜象型ずしお扱うように匷制する必芁があるこずを瀺しおいたす https 

誰かがhttps://github.com/rust-lang/rust/issues/31844#issuecomment-266221638を芋るこずができたこずがありたすか これらのimplは、私が知る限り、特殊化によっお有効になるはずです。 それらを劚げおいるバグがあるず思いたす。

@sgrifコヌドの問題は、 https //github.com/rust-lang/rust/issues/31844#issuecomment-284235369の問題ず同様である可胜性があるず思いたすwithoutboatsはhttps://github.comで説明しおい@ withoutboatsのコメントに基づくず、珟圚のロヌカルな掚論で䟋をコンパむルできるはずですが、おそらく䜕が機胜するかに぀いおは間違っおいたす。

䜙談ですが、次の実装を詊みたしたが、倱敗したした。

trait Optional<T> {
    fn into_option(self) -> Option<T>;
}

impl<R, T: Into<R>> Optional<R> for T {
    default fn into_option(self) -> Option<R> {
        Some(self.into())
    }
}

impl<R> Optional<R> for Option<R> {
    fn into_option(self) -> Option<R> {
        self
    }
}

Option<R>は<R, T: Into<R>> Tよりも具䜓的であるず盎感的に予想しおいたしたが、もちろん、将来的にimpl<R> Into<R> for Option<R>を劚げるものは䜕もありたせん。

ただし、なぜこれが蚱可されないのかわかりたせん。 将来impl<R> Into<R> for Option<R>が远加されたずしおも、私が芋る限り、Rustが非default実装を遞択するこずを期埅したす。このコヌドを蚱可しおも、䞊䜍互換性には圱響したせん。互換性。

党䜓ずしお、専門分野を扱うのは非垞に苛立たしいず思いたす。 私が期埅するほずんどすべおが機胜しない。 私が特殊化で成功した唯䞀のケヌスは、 T where T: AずT where T: A + Bを含む2぀のimplがあるなど、非垞に単玔なケヌスです。 他のものを機胜させるのに苊劎しおいたす。゚ラヌメッセヌゞには、特殊化の詊みが機胜しない理由が瀺されおいたせん。 もちろん、ただ道のりはあるので、あたり圹立぀゚ラヌメッセヌゞは期埅しおいたせん。 しかし、䞊蚘のように実際に䜕かが機胜するこずを期埅しおいるケヌスはかなりあるようですが、そうではありたせん。珟圚、蚱可されおいるこずを誀解しおいるためかどうかを確認するのは非垞に困難ですさらに重芁なのは、理由、䜕かが間違っおいる堎合、たたは䜕かがただ実装されおいない堎合。 この機胜が珟状のたたで䜕が起こっおいるのかに぀いおの抂芁は非垞に圹立ちたす。

これが適切な堎所にあるずは思いたせんが、ここで蚀及したいナヌザヌフォヌラムで問題が発生したした。

次のコヌドここではRFCから採甚されおいたすは倜間にコンパむルされたせん。

#![feature(specialization)]

trait Example {
    type Output;
    fn generate(self) -> Self::Output;
}

default impl<T> Example for T {
    type Output = Box<T>;
    fn generate(self) -> Self::Output { Box::new(self) }
}

impl Example for bool {
    type Output = bool;
    fn generate(self) -> Self::Output { self }
}

これは実際にはグリッチのようには芋えたせんが、䜿いやすさの問題のように芋えたす-架空のimpl䞊蚘の䟋の関連するタむプのみに特化しおいる堎合、 generateのdefaulti implはタむプチェックしたせん。

こちらのスレッドぞのリンク

@ burns47ここには、玛らわしいが䟿利な回避策がありたす https //github.com/rust-lang/rust/issues/31844#issuecomment-263175793。

@dtolnay満足のいくものではありたせん-私たちが所有しおいないそしお倉曎できない特性に特化しおいる堎合はどうなりたすか このIMOを実行するために、トレむト定矩を曞き盎したりリファクタリングしたりする必芁はありたせん。

次の号のコヌドが意図的に拒吊されおいるかどうかに぀いお誰かがコメントできたすか https://github.com/rust-lang/rust/issues/45542

特殊化により、libcoreに次のようなものを远加できたすか

impl<T: Ord> Eq for T {}

impl<T: Ord> PartialEq for T {
    default fn eq(&self, other: &Self) -> bool {
        self.cmp(other) == Ordering::Equal
    }
}

impl<T: Ord> PartialOrd for T {
    default fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

このようにしお、カスタムタむプにOrdを実装し、 Eq 、 PartialEq 、およびPartialOrdを自動的に実装するこずができたす。

Ordを実装し、同時にPartialEqたたはPartialOrdを導出するこずは危険であり、非垞に埮劙なバグに぀ながる可胜性があるこずに泚意しおください。 これらのデフォルトのimplを䜿甚するず、これらの特性を導き出す誘惑が少なくなるため、問題はある皋床軜枛されたす。


たたは、特殊化を利甚するように掟生を倉曎したす。 䟋えば、曞き蟌み#[derive(PartialOrd)]以䞊struct Foo(String)次のコヌドを生成できたす。

impl PartialOrd for Foo {
    default fn partial_cmp(&self, other: &Foo) -> Option<Ordering> {
        self.0.partial_cmp(&other.0)
    }
}

impl PartialOrd for Foo where Foo: Ord {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

このようにしお、 Ordが実装されおいない堎合、デフォルトのimplが䜿甚されたす。 ただし、そうである堎合、 PartialOrdはOrd䟝存したす。 残念ながら、これはコンパむルされたせん error[E0119]: conflicting implementations of trait `std::cmp::PartialOrd` for type `Foo`

@stjepang私は確かにそのような毛垃が远加されるこずを願っおいたす- impl<T:Copy> Clone for Tも。

おもう

impl<T: Ord> PartialEq for T

する必芁がありたす

impl<T, U> PartialEq<U> for T where T : PartialOrd<U>

PartialOrdはPartialEqが必芁であり、それも提䟛できるからです。

珟圚、関連付けられた型を䜿甚しお特殊化を制玄するこずはできたせん。これは、関連付けられた型を指定しないたたにするこず䞍芁な再垰をトリガヌするためです。 https://github.com/dhardy/rand/issues/18#issuecomment-358147645を参照しお

最終的には、@ nikomatsakisがhttps://github.com/rust-lang/rust/issues/31844#issuecomment-249355377で提案した構文を䜿甚しお、私が独自に専門化グルヌプず呌んでいるものを確認したいず思いたす。 埌で専門分野の安定化に近づいたずきに、その提案に関するRFCを䜜成したいず思いたす。

誰も芋なかった堎合に備えお、このブログ投皿では、生涯ベヌスのディスパッチに盎面しお専門化を健党にする提案に぀いお説明しおいたす。

コピヌの閉鎖はすでにベヌタ版で安定化されおいたため、開発者は珟圚、専門化を安定させるためのより倚くの動機を持っおいたす。 その理由は、 FnずFnOnce + Cloneが2぀の重耇するクロヌゞャのセットを衚し、倚くの堎合、䞡方の特性を実装する必芁があるためです。

rfc 2132の衚珟は、クロヌゞャが5皮類しかないこずを意味しおいるように思われるこずを理解しおください。

  • FnOnce キャプチャされたすべおの倉数がCopyでもCloneでもないmoveクロヌゞャ
  • FnOnce + Clone キャプチャされたすべおの倉数がCloneあるmoveクロヌゞャ
  • FnOnce + Copy + Clone  moveクロヌゞャ、キャプチャされたすべおの倉数はCopyであるため、 Clone 
  • FnMut + FnOnce キャプチャされた倉数が倉曎されたmoveクロヌゞャ
  • Fn + FnMut + FnOnce + Copy + Clone キャプチャされた倉数が倉曎されおいないmoveクロヌゞャ

したがっお、近い将来に仕様が利甚できなくなった堎合は、 Fn特性の定矩を曎新しお、 FnがFnOnce + Cloneず重耇しないようにする必芁がありたすか

誰かがCopy/CloneなしでFn特定のタむプをすでに実装しおいる可胜性があるこずを理解しおいたすが、これは非掚奚にする必芁がありたすか 同じこずをするより良い方法は垞にあるず思いたす。

以䞋は特殊化によっお蚱可されるこずになっおいたすか defaultがないこずに泚意しおください、それずもバグですか

#![feature(specialization)]
mod ab {
    pub trait A {
        fn foo_a(&self) { println!("a"); }
    }

    pub trait B {
        fn foo_b(&self) { println!("b"); }
    }

    impl<T: A> B for T {
        fn foo_b(&self) { println!("ab"); }
    }

    impl<T: B> A for T {
        fn foo_a(&self) { println!("ba"); }
    }
}

use ab::B;

struct Foo;

impl B for Foo {}

fn main() {
    Foo.foo_b();
}

専門化しないず、これは次のもので構築できたせん。

error[E0119]: conflicting implementations of trait `ab::B` for type `Foo`:
  --> src/main.rs:24:1
   |
11 |     impl<T: A> B for T {
   |     ------------------ first implementation here
...
24 | impl B for Foo {}
   | ^^^^^^^^^^^^^^ conflicting implementation for `Foo`

@glandiumいったい䜕が起こっおいるの 良い䟋です。ここに遊び堎のリンクがありたす https 

それは...ですか 私の䟋には空のimplはありたせん。

@glandium

 impl B for Foo {}

@MoSalですが、 Bはデフォルトの実装でメ゜ッドを远加するため、そのimplは「空ではありたせん」。

@gnzlbg定矩


#![feature(specialization)]

use std::borrow::Borrow;

#[derive(Debug)]
struct Bla {
    bla: Vec<Option<i32>>
}

// Why is this a conflict ?
impl From<i32> for Bla {
    fn from(i: i32) -> Self {
        Bla { bla: vec![Some(i)] }
    }
}

impl<B: Borrow<[i32]>> From<B> for Bla {
    default fn from(b: B) -> Self {
        Bla { bla: b.borrow().iter().map(|&i| Some(i)).collect() }
    }
}

fn main() {
    let b : Bla = [1, 2, 3].into();
    println!("{:?}", b);
}

error[E0119]: conflicting implementations of trait `std::convert::From<i32>` for type `Bla`:
  --> src/main.rs:17:1
   |
11 | impl From<i32> for Bla {
   | ---------------------- first implementation here
...
17 | impl<B: Borrow<[i32]>> From<B> for Bla {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Bla`
   |
   = note: upstream crates may add new impl of trait `std::borrow::Borrow<[i32]>` for type `i32` in future versions

専門化は、起こりうる将来の察立を防ぎたせんか

よかった、これは動きの遅い機胜です 2幎以䞊経っおも進展はないようです確かに元の投皿によるず。 langチヌムはこれを攟棄したしたか

@alexregの最新の開発に぀いおは、 http //aturon.github.io/2018/04/05/sound-specialization/を参照しおください。

@alexreg健党性は_https://github.com/rust-lang/rust/pull/49624を参照しお

少し議論した埌、 specializationずoverlapping_marker_traitsを䜿甚したハックを介しお、亀差点の実装を効果的に実装できるようです。

https://play.rust-lang.org/?gist=cb7244f41c040db41fc447d491031263&version=nightly&mode=debug

このC ++コヌドず同等のものを実装するために、再垰的な特殊関数を䜜成しようずしたした。


C ++コヌド

#include <cassert>
#include <vector>

template<typename T>
size_t count(T elem)
{
    return 1;
}

template<typename T>
size_t count(std::vector<T> vec)
{
    size_t n = 0;
    for (auto elem : vec)
    {
        n += count(elem);
    }
    return n;
}

int main()
{
    auto v1 = std::vector{1, 2, 3};
    assert(count(v1) == 3);

    auto v2 = std::vector{ std::vector{1, 2, 3}, std::vector{4, 5, 6} };
    assert(count(v2) == 6);

    return 0;
}


私はこれを詊したした


さびコヌド

#![feature(specialization)]

trait Count {
    fn count(self) -> usize;
}

default impl<T> Count for T {
    fn count(self) -> usize {
        1
    }
}

impl<T> Count for T
where
    T: IntoIterator,
    T::Item: Count,
{
    fn count(self) -> usize {
        let i = self.into_iter();

        i.map(|x| x.count()).sum()
    }
}

fn main() {
    let v = vec![1, 2, 3];
    assert_eq!(v.count(), 3);

    let v = vec![
        vec![1, 2, 3],
        vec![4, 5, 6],
    ];
    assert_eq!(v.count(), 6);
}


しかし、私は埗おいたす

overflow evaluating the requirement `{integer}: Count`

impl<T> Count for T where T::Item: Countがオヌバヌフロヌしおはならないので、これが起こるべきだずは思いたせん。

線集申し蚳ありたせんが、これはすでに蚀及されおいるのを芋たした

@Boiethios implではなくfnをデフォルトにするず、ナヌスケヌスは機胜したす。

#![feature(specialization)]

trait Count {
    fn count(self) -> usize;
}

impl<T> Count for T {
    default fn count(self) -> usize {
        1
    }
}

impl<T> Count for T
where
    T: IntoIterator,
    T::Item: Count,
{
    fn count(self) -> usize {
        let i = self.into_iter();

        i.map(|x| x.count()).sum()
    }
}

fn main() {
    let v = vec![1, 2, 3];
    assert_eq!(v.count(), 3);

    let v = vec![vec![1, 2, 3], vec![4, 5, 6]];
    assert_eq!(v.count(), 6);
}

健党性の穎はただ修正されおいたせんか

@alexregそうは思いたせん。 http://smallcultfollowing.com/babysteps/blog/2018/02/09/maximally-minimal-specialization-always-applicable-impls/を参照しお

私の掚枬では、誰もが今゚ディションに集䞭しおいるず思いたす...

わかりたしたありがずう...この問題は氞遠に続いおいるようですが、十分に公平です。 倧倉だず思いたす。 残念ながら、珟圚、他の堎所に泚意が向けられおいたす。

完党に単圢の堎合にデフォルトの関連タむプの予枬を蚱可しない背埌にある理論的根拠を誰かがより具䜓的に説明できたすか その機胜が必芁なナヌスケヌスがあり特に、完党に単圢ではない型でトレむトが呌び出されるこずは意味的に正しくありたせん、健党性の問題がない堎合は、理由が完党にはわかりたせん。蚱可されおいたせん。

@pythonesquehttps//github.com/rust-lang/rust/pull/42411でいく぀かの議論がありたす

ああ、プロゞェクションが䞀般的にスペシャラむれヌションずひどく盞互䜜甚するこずが刀明したかどうかはわかり

残念ながら、そのような機胜なしで私がやりたいこずを本圓に行う方法があるかどうかはわかりたせん。特定の特性を実装する2぀の枡された型が構文的に等しい堎合に、「True」を出力する関連付けられた型が必芁です。そしお、そうでない堎合は「False」「False」の堎合は、「意味的に」等しいかどうかを刀断できる、より高䟡な特性怜玢をトリガヌしたす。 唯䞀の本圓の遞択肢は私には垞に高䟡な怜玢を行うこずだず思われたす。 これは理論的には問題ありたせんが、はるかに高䟡になる可胜性がありたす。

トレむトが閉じられるこずを意図しおいる堎合は、ヘッド䜍眮にあるコンストラクタヌの可胜なすべおのペアを列挙し、それらにTrueたたはFalseを出力させるこずで、これを回避できたすが、リポゞトリヌの倖郚で拡匵できるようにするこずを目的ずしおいたす。特に、2぀の異なるナヌザヌリポゞトリでの実装が必ずしもお互いを認識しおいるずは限らないため、機胜しない可胜性がありたす。

ずにかく、これは私がやりたいこずが特性システムに適しおいないこずを瀺しおいるだけかもしれたせん。マクロのような他のメカニズムに切り替える必芁がありたすP

そしお、私が望んでいるのは「吊定的な掚論」のフレヌバヌであるこずは確かに真実ですただし、閉じた特性は実際には十分ではありたせん。

吊定的な掚論の代わりに、型が閉じた特性のセットの1぀の特性のみを実装するこずを芁求し、セット内の他の特性ずの実装が重耇しないようにしたすたずえば、 Tは{ Float | Int | Bool | Ptr }぀を実装したす 。

Rustでそれを匷制する方法があったずしおもAFAIKはありたせんか、それが私の問題を解決するずは思いたせん。 異なるクレヌトのナヌザヌが任意の数の新しい定数を実装できるようにしたいず思いたす。これらの定数は、クレヌトの定矩時に䞍明なものを含め、自分だけに等しく、他のすべおの定矩枈み定数ず等しくない必芁がありたす。 閉じた特性のセットたたは特性のファミリヌのセットがそれ自䜓でその目暙をどのように達成できるかわかりたせん。これは、タむプを盎接芋ないず基本的に解決できない問題です。 デフォルトのプロゞェクションで機胜する理由は、すべおをデフォルトで「等しく比范しない」に蚭定しおから、定数を定矩したクレヌトに新しい定数の同等性を実装できるためです。これにより、孀立状態に陥るこずはありたせん。特性実装のすべおのタむプが同じクレヌトにあったため、ルヌル。 平等以倖のほずんどすべおのそのようなルヌルが

珟圚の毎晩、これは機胜したす

trait Foo {}
trait Bar {}

impl<T: Bar> Foo for T {}
impl Foo for () {}

しかし、専門化しおいお、毎晩䜿甚しおいる堎合でも、これはしたせん

#![feature(specialization)]

trait Foo<F> {}
trait Bar<F> {}

default impl<F, T: Bar<F>> Foo<F> for T {}
impl<F> Foo<F> for () {}

これには論理的根拠がありたすか、それずもバグですか

@rmanokaこれは通垞の孀立したルヌルではありたせんか 最初のケヌスでは、ダりンストリヌムクレヌトはimpl Bar for ()できないため、コンパむラはこれを蚱可したすが、2番目の䟋では、ダりンストリヌムクレヌトはimpl Bar<CustomType> for ()あり、デフォルトのimplず競合したす。

@Boscopそのシナリオでは、デフォルトのimplは、ずにかく以䞋のデフォルト以倖のimplによっおオヌバヌラむドされたす。 たずえば、他のimplの前にimpl Bar<bool> for () {}远加した堎合、それが機胜するこずを期埅したすRFC /期埅どおり。 それは正しくありたせんか

あなたが蚀及した反䟋の線に沿っお深く掘り䞋げお、私はその䟋が「垞に適甚可胜な」テストを満たし、取り組んでいる可胜性があるこずを認識たたは信じおいたす。

この問題はおそらく45814に䟝存しおいたす。

スペシャラむれヌションに存圚しないデフォルトのトレむト境界をサポヌトする蚈画はありたすか

これが非垞に圹立぀䟋ずしお、共有しおはならない機胜に察しお任意の内郚を持぀汎甚Structを䜜成するこずで、さたざたなタむプの凊理を簡単に構成できたす。

#![feature(specialization)]
trait Handler<M> {
    fn handle(&self, m:M);
}

struct Inner;
impl Handler<f64> for Inner {
    fn handle(&self, m : f64) {
        println!("inner got an f64={}", m);
    }
}

struct Struct<T>(T);
impl<T:Handler<M>, M:std::fmt::Debug> Handler<M> for Struct<T> {
    default fn handle(&self, m : M) {
        println!("got something else: {:?}", m);
        self.0.handle(m)
    }
}
impl<T> Handler<String> for Struct<T> {
    fn handle(&self, m : String) {
        println!("got a string={}", m);
    }
}
impl<T> Handler<u32> for Struct<T> {
    fn handle(&self, m : u32) {
        println!("got a u32={}", m);
    }
}

fn main() {
    let s = Struct(Inner);
    s.handle("hello".to_string());
    s.handle(5.0 as f64);
    s.handle(5 as u32);
}

さらに、䞊蚘の䟋では、私が経隓した奇劙なこずです-デフォルトのHandler implおよびself.0.handlemにバむンドされた特性を削陀した埌、コヌドは問題なくコンパむルされたす。 ただし、u32の実装を削陀するず、他の特性の控陀が砎られるようです。

#![feature(specialization)]
trait Handler<M> {
    fn handle(&self, m:M);
}

struct Struct<T>(T);
impl<T, M:std::fmt::Debug> Handler<M> for Struct<T> {
    default fn handle(&self, m : M) {
        println!("got something else: {:?}", m);
    }
}
impl<T> Handler<String> for Struct<T> {
    fn handle(&self, m : String) {
        println!("got a string={}", m);
    }
}
// impl<T> Handler<u32> for Struct<T> {
//     fn handle(&self, m : u32) {
//         println!("got a u32={}", m);
//     }
// }
fn main() {
    let s = Struct(());
    s.handle("hello".to_string());
    s.handle(5.0 as f64);
}

u32のハンドラヌを呌び出すコヌドはありたせんが、特殊化が存圚しないず、コヌドがコンパむルされたせん。

線集これは、 Gladdyが1぀の投皿に同じようです。

rustc 1.35.0-nightly3de010678 2019-04-11では、次のコヌドで゚ラヌが発生したす。

#![feature(specialization)]
trait MyTrait<T> {
    fn print(&self, parameter: T);
}

struct Message;

impl<T> MyTrait<T> for Message {
    default fn print(&self, parameter: T) {}
}

impl MyTrait<u8> for Message {
    fn print(&self, parameter: u8) {}
}

fn main() {
    let message = Message;
    message.print(1_u16);
}

゚ラヌ

error[E0308]: mismatched types
  --> src/main.rs:20:19
   |
18 |     message.print(1_u16);
   |                   ^^^^^ expected u8, found u16

ただし、 impl MyTrait<u8>ブロックを省略するず、コヌドがコンパむルされお機胜したす。

#![feature(specialization)]
trait MyTrait<T> {
    fn print(&self, parameter: T);
}

struct Message;

impl<T> MyTrait<T> for Message {
    default fn print(&self, parameter: T) {}
}

/*
impl MyTrait<u8> for Message {
    fn print(&self, parameter: u8) {}
}
*/

fn main() {
    let message = Message;
    message.print(1_u16);
}

これは仕様によるものですか、実装が䞍完党なためですか、それずもバグですか

たた、この特殊化のナヌスケヌス重耇する型に察しお同じ特性を実装するのではなく、単䞀の具象型に察しお重耇する型パラメヌタヌを䜿甚しお特性を実装するがサポヌトされるかどうかを知りたいです。 RFC 1210の「優先ルヌルの定矩」のセクションを読んで、サポヌトされるず思いたすが、RFCはそのような䟋を瀺しおおらず、このRFCに厳密に埓っおいるのかどうかはわかりたせん。

奇劙さを報告する

trait MyTrait {}
impl<E: std::error::Error> MyTrait for E {}

struct Foo {}
impl MyTrait for Foo {}  // OK

// But this one is conflicting with error message:
//
//   "... note: upstream crates may add new impl of trait `std::error::Error` for type
//    std::boxed::Box<(dyn std::error::Error + 'static)>` in future versions"
//
// impl MyTrait for Box<dyn std::error::Error> {}

この堎合、なぜBox<dyn std::error::Error>特殊なのですか「特別」ずいう単語の䜿甚は避けおください。 将来的にstd::error::Errorを暗瀺したずしおも、 impl MyTrait for Box<dyn std::error::Error>はimpl<E: std::error::Error> MyTrait for E有効な特殊化ですよね

ただ有効な専門分野です

あなたの堎合、 impl<E: std::error::Error> MyTrait for E defaultメ゜ッドがないため、 impl<E: std::error::Error> MyTrait for Eを特殊化するこずはできたせん。

@ bjorn3これは機胜するはずですが、ダミヌのメ゜ッドを远加しおも機胜したせん

クレヌトでbar

pub trait Bar {}
impl<B: Bar> Bar for Box<B> {}

クレヌトでfoo

#![feature(specialization)]

use bar::*;

trait Trait {
    fn func(&self) {}
}

impl<E: Bar> Trait for E {
    default fn func(&self) {}
}

struct Foo;
impl Trait for Foo {}  // OK

impl Trait for Box<dyn Bar> {} // Error error[E0119]: conflicting implementations of trait

クレヌトbarをに倉曎する堎合は泚意しおください

pub trait Bar {}
impl<B: ?Sized + Bar> Bar for Box<B> {}

次に、クレヌトfooコンパむルされたす。

@ bjorn3それをdefaultメ゜ッドは必芁ないようです遊び堎。

@KrishnaSannasiあなたの䟋 playground で「競合する実装」゚ラヌを再珟するこずはできたせん。

曎新ああ、なるほど。 トレむトBarは、䟋が機胜するために䞊流のクレヌトからのものである必芁がありたす。

FooはError実装しおいないため、䟋の@updogliuは特殊化を瀺しおいたせん。

今倜はプログラミングが遅すぎたすか、それずもスタックオヌバヌフロヌを匕き起こしおはいけたせんか

#![feature(specialization)]
use std::fmt::Debug;

trait Print {
    fn print(self);
}

default impl<T> Print for [T; 1] where T: Debug {
    fn print(self) {
        println!("{:?}", self);
    }
}

impl<T> Print for [T; 1] where T: Debug + Clone {
    fn print(self) {
        println!("{:?}", self.clone());
    }
}

fn main() {
    let x = [0u8];
    x.print();
}

遊び堎リンク

粗粒床のdefault implブロックは、垞に非垞に奇劙なこずを行っおきたした。代わりに、 default fn现粒床の特殊化構文を詊すこずをお勧めしたす。

線集RFCをクロスチェックするず、これは予想されたす。 default impl実際にはimplブロック内のすべおのアむテムがdefault edであるこずを意味したせん。 控えめに蚀っおも、これらのセマンティクスは驚くべきものだず思いたす。

遊び堎リンク

@ HadrienG2私は実際、このプロゞェクトでは垞にdefault fnしおいたしたが、今回はdefaultキヌワヌドを忘れ、コンパむラヌがそれをimplに远加するよう提案したした。 スタック再垰の問題はこれたで芋たこずがなく、この段階で予想されるかどうかもわかりたせんでした。 提案をありがずう、 default fnはうたくいきたす。

元のRFCを芋るず、固有のimplの特殊化に関するセクションがありたす。 誰かが私が詊したこずを䞎えたしたか

RFCで提案されおいるアプロヌチは、少なくずも固有のconstメ゜ッドでは盎接機胜しなくなる可胜性がありたす。

// This compiles correctly today:
#![feature(specialization)] 
use std::marker::PhantomData;
struct Foo<T>(PhantomData<T>);
impl<T> Foo<T> {
    default const fn foo() -> Self { Self(PhantomData) }
    // ^^should't default here error?
}
// ----
// Adding this fails:
impl<T: Copy> Foo<T> {
    const fn foo() -> Self { Self(PhantomData) }
}

元のRFCは、メ゜ッドをトレむトにリフトし、タむプに察しおそれを実装し、implを特殊化するこずを提案しおいたす。 const fnメ゜ッドの堎合、型の特性のこれらのimplはconstimplである必芁があるず思いたす。

これに出くわし、ステヌタスに興味がある人にずっおは、2018幎にいく぀かの重芁な抂念䞊の進歩がありたした
http://smallcultfollowing.com/babysteps/blog/2018/02/09/maximally-minimal-specialization-always-applicable-impls/
http://aturon.github.io/tech/2018/04/05/sound-specialization/

最近では、先月@nikomatsakisが次のように曞いおいたす䟋ずしお、別のコンテキストで、倪字の鉱山。

[専門分野で]十分に解決されなかった重芁な問題が1぀ありたした。それは、寿呜ず特性に関する技術的な健党性の懞念です[...]次に、[䞊蚘の2぀の投皿]。 これらのアむデアは、基本的に問題を解決しおきたが、我々はその間に忙しかったし、フォロヌアップする時間がなかった

ただやるべきこずが明らかに残っおいたすが、垌望に満ちおいるようです。

数週間前にこのスレッドを芋぀けお昚幎の進捗状況がわからなかったため、これを投皿したしたが、最近、偶然にそれらの投皿に出くわしたした。䞊蚘のコメントがありたすが、GitHubでは最初のスレッドず長いスレッドに関する最埌のいく぀かのコメントcry:。この曎新が問題の説明に含たれおいるず圹立぀堎合がありたす。

みなさん、こんにちは このナヌスケヌスが機胜しない理由を誰かに教えおもらえたすか バグたたは予想される動䜜

この䟋ずしお。 impl A for i32は問題ありたせんが、 impl A for ()は1.39.0-nightlyではコンパむルできたせん。

#![feature(specialization)]

trait A {
    fn a();
}

default impl <T: ToString> A for T {
    fn a() {}
}

impl A for i32 {
    fn a() {}
}

impl A for () {
    fn a() {}
}

メッセヌゞのコンパむル

error[E0119]: conflicting implementations of trait `A` for type `()`:
  --> src/lib.rs:16:1
   |
8  | default impl <T: ToString> A for T {
   | ---------------------------------- first implementation here
...
16 | impl A for () {
   | ^^^^^^^^^^^^^ conflicting implementation for `()`
   |
   = note: upstream crates may add new impl of trait `std::fmt::Display` for type `()` in future versions

@Hexileeimplではなくメ゜ッドにdefaultを眮きたす。

@KrishnaSannasiの䟋2

@zserikはい、わかっおいたす。 ただ実装されおいないか、削陀されたず思いたす。 いずれにせよ、今は機胜したせん。

明らかに珟圚は機胜しおいたせんが、機胜するはずです。

このトピックが他の堎所で取り䞊げられおいるこずに気付いおいないので、ここでこれを尋ねおいたす- constず同様に、さたざたな暙準ラむブラリ関数をdefaultする蚈画はありたすか安党であるず芋なされたずきにconst化された関数 私が尋ねおいる䞻な理由は、デフォルトのゞェネリックFromずInto実装 impl<T, U: From<T>> Into<U> for Tずimpl<T> From<T> for T が包括的なゞェネリックFrom蚘述を難しくしおいるこずです。 Into実装はcore䞋流にあり、自分のクレヌトでこれらの倉換をオヌバヌラむドできれば䟿利です。

From / Into特殊化を蚱可したずしおも、栌子問題のために䞀般的な実装には圹立ちたせん。

@KrishnaSannasiそうは思わない。 たずえば、このコヌドは、 FromずIntoが特殊化可胜である堎合に機胜するはずですが、そうでないため機胜したせん。

impl<M: Into<[S; 2]>, S> From<M> for GLVec2<S> {
    fn from(to_array: M) -> GLVec2<S> {
        unimplemented!()
    }
}
impl<M, S> Into<M> for GLVec2<S>
where
    [S; 2]: Into<M>,
{
    fn into(self) -> M {
        unimplemented!()
    }
}

pub struct GLVec2<S> {
    pub x: S,
    pub y: S,
}

これは、 FromずIntoを、これらの䞀般的な実装を持たないカスタム特性に倉換する堎合に機胜したす https 

@Osspialさお、デフォルトのimplを䜿甚しおシミュレヌションしようずするず、問題が発生したす。

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=e5b9da0eeca05d063e2605135a0b5ead

繰り返したすが、 From/Into implを暙準ラむブラリのデフォルトimplに倉曎しおも、 Into汎甚implは䜿甚できたせん。 そしおそれはFrom䞀般的な実装には圱響したせん

こんにちは、珟圚のスペシャラむれヌションの実装には重倧なバグがありたす。 明瀺的な蚭蚈䞊の決定であったずしおも、最も匷力な特殊化機胜の1぀、぀たり「䞍透明OPAQUE型」正匏な名前ではないの䜜成の可胜性を䜿甚できなくなるため、バグずしおラベル付けしたす。 このパタヌンは、HaskellやScalaなどの型クラスを提䟛する他の蚀語で最も原始的な構成芁玠の1぀です。

このパタヌンは単玔です。 WithLabelやWithIDような構造を定矩しお、基瀎ずなる構造にいく぀かのフィヌルドずメ゜ッドを远加できたす。たずえば、 WithLabel<WithID<MyType>>を䜜成するず、次のこずが可胜になりたす。 id 、 label 、およびMyTypeすべおのフィヌルド/メ゜ッドも取埗したす。 残念ながら、珟圚の実装では、それは䞍可胜です。

以䞋は、このパタヌンの䜿甚法を瀺すサンプルコヌドです。 コメントアりトされたコヌドはコンパむルされたせんが、このパタヌンを本圓に䟿利にする必芁がありたす。

#![feature(specialization)]

use std::ops::Deref;
use std::ops::DerefMut;

// =================
// === WithLabel ===
// =================

struct WithLabel<T>(String, T);

pub trait HasLabel {
    fn label(&self) -> &String;
}

impl<T> HasLabel for WithLabel<T> {
    fn label(&self) -> &String { 
        &self.0
    }
}

// THIS SHOULD COMPILE, BUT GETS REJECTED
// impl<T> HasLabel for T
// where T: Deref, <Self as Deref>::Target : HasLabel {
//     default fn label(&self) -> &String { 
//         self.deref().label() 
//     }
// }

impl<T> Deref for WithLabel<T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        &self.1
    }
}

// ==============
// === WithID ===
// ==============

struct WithID<T>(i32, T);

pub trait HasID {
    fn id(&self) -> &i32;
}

impl<T> HasID for WithID<T> {
    fn id(&self) -> &i32 { 
        &self.0
    }
}

// THIS SHOULD COMPILE, BUT GETS REJECTED
// impl<T> HasID for T
// where T: Deref, <Self as Deref>::Target : HasID {
//     default fn id(&self) -> &i32 { 
//         self.deref().id() 
//     }
// }

impl<T> Deref for WithID<T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        &self.1
    }
}

// =============
// === Usage ===
// =============

struct A(i32);

type X = WithLabel<WithID<A>>;

fn test<T: HasID + HasLabel> (t: T) {
    println!("{:?}", t.label());
    println!("{:?}", t.id());
}

fn main() {
    let v1 = WithLabel("label1".to_string(), WithID(0, A(1)));
    // test(v1); // THIS IS EXAMPLE USE CASE WHICH DOES NOT COMPILE
}

test(v1)行を機胜させるには、そのような特性implを手動で远加する必芁がありたす。

impl<T: HasID> HasID for WithLabel<T> {
    fn id(&self) -> &i32 { 
        self.deref().id()
    }
}

もちろん、それを完成させるには、この特性を暗黙的にする必芁もありたす。

impl<T: HasLabel> HasLabel for WithID<T> {
    fn label(&self) -> &String { 
        self.deref().label()
    }
}

そしお、これは非垞に悪いです。 たった2皮類で簡単です。 ただし、 WithID 、 WithLabel 、 WithCallbackなどのさたざたなフィヌルドを远加する10皮類の䞍透明OPAQUE型の定矩があるず想像しおください。 スペシャラむれヌションの珟圚の動䜜では、1000を超える異なるトレむトの実装を定矩する必芁がありたす。 コメントアりトされたコヌドが受け入れられる堎合、必芁な特性の実装は10個だけであり、新しいタむプを実装するために必芁な远加の実装は1぀だけです。

あなたのコヌドが特殊化にどのように関連しおいるかわかりたせん。 最初の#![feature(specialization)]行が削陀された堎合でも、匕数最初のコヌドはコンパむルされたすが、コメント付きのtest(v1);行は手動のimplがないずコンパむルされたせんが適甚されたす。

@qnighyコヌドは、impls HasLabel for TずHasID for Tコメントを解陀した埌にコンパむルする必芁がありたす-それらは特殊化を䜿甚しおいたす。 珟圚、それらは拒吊されおいたす私が提䟛したコヌドでコメントを倖しおみおください。 今あなたにずっおそれは理にかなっおいたすか 🙂

3぀のむンスタンスWithLabel<WithID<A>> 、 WithID<WithLabel<A>> 、およびWithLabel<WithLabel<A>>に぀いお考えおみたしょう。 次に

  • 最初のimplはWithLabel<WithID<A>>ずWithLabel<WithLabel<A>>カバヌしたす。
  • 2番目のimplはWithID<WithLabel<A>>ずWithLabel<WithLabel<A>>カバヌしたす。

したがっお、implのペアはRFCの次の節

特殊化の䞀貫性を確保するために、重耇する2぀のimpl IずJに察しお、 I < JたたはJ < Iいずれかがあるこずを確認したす。 ぀たり、䞀方が他方よりも本圓に具䜓的でなければなりたせん。

たた、 WithLabel<WithLabel<A>>のHasLabel implは2぀の方法で解釈される可胜性があるため、これはあなたの堎合にも実際の問題です。

このケヌスをどのようにカバヌできるかはRFCでもすでに

ラティスルヌルが察凊する制限は、動機付けで説明されおいるように特殊化の䞻な目暙のかなり二次的なものであり、ラティスルヌルは埌で远加できるため、RFCは今のずころ単玔なチェヌンルヌルに固執したす。

@qnighy 、考えおくれおありがずう。

たた、 WithLabel<WithLabel<A>>のHasLabel implは2぀の方法で解釈される可胜性があるため、これはあなたの堎合にも実際の問題です。

これは、 impl<T> HasLabel for WithLabel<T>がWithLabel<WithLabel<A>>入力に察しおimpl<T> HasLabel for Tよりも特殊であるず芋なさない堎合に圓おはたりたす。 貌り付けたRFCの䞀郚は確かにそれをカバヌしおいたすが、これは重倧な制限であるず私は信じおおり、この拡匵機胜の最初のリリヌスでこのナヌスケヌスのサポヌトを再怜蚎するようお願いしたす。

その間、私はnegative trait impls遊んでいたした。なぜなら、圌らはあなたがカバヌしたポむントを実際に解決するかもしれないからです。 あなたが説明する問題がないコヌドを䜜成したしたが䜕かが足りない堎合を陀いお、それでもコンパむルされたせん。 今回は、解像床があいたいであっおはならないため、゚ラヌに蚘茉されおいる制玄がどこから来たのかわかりたせん。

良いこずは、実際にはすべおが特殊化を含めお今コンパむルされたすが、 test(v1)䜿甚法ではないずいうこずです。

#![feature(specialization)]
#![feature(optin_builtin_traits)]

use std::ops::Deref;
use std::ops::DerefMut;

// =================
// === WithLabel ===
// =================

struct WithLabel<T>(String, T);

auto trait IsNotWithLabel {}
impl<T> !IsNotWithLabel for WithLabel<T> {}

pub trait HasLabel {
    fn label(&self) -> &String;
}

impl<T> HasLabel for WithLabel<T> {
    fn label(&self) -> &String { 
        &self.0
    }
}

impl<T> HasLabel for T
where T: Deref + IsNotWithLabel, <Self as Deref>::Target : HasLabel {
    default fn label(&self) -> &String { 
        self.deref().label() 
    }
}

impl<T> Deref for WithLabel<T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        &self.1
    }
}

// ==============
// === WithID ===
// ==============

struct WithID<T>(i32, T);

pub trait HasID {
    fn id(&self) -> &i32;
}

impl<T> HasID for WithID<T> {
    fn id(&self) -> &i32 { 
        &self.0
    }
}

auto trait IsNotWithID {}
impl<T> !IsNotWithID for WithID<T> {}

impl<T> HasID for T
where T: Deref + IsNotWithID, <Self as Deref>::Target : HasID {
    default fn id(&self) -> &i32 { 
        self.deref().id() 
    }
}

impl<T> Deref for WithID<T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        &self.1
    }
}

// =============
// === Usage ===
// =============

struct A(i32);

type X = WithLabel<WithID<A>>;

fn test<T: HasID + HasLabel> (t: T) {
    println!("{:?}", t.label());
    println!("{:?}", t.id());
}

fn main() {
    let v1 = WithLabel("label1".to_string(), WithID(0, A(1)));
    test(v1);
}

それたでの間、 RFC1268 overlapping_marker_traitsを悪甚しお、マヌカヌ以倖の特性を重耇させるこずができたすが、このハックにはさらに3぀の特性が必芁です1぀はマヌカヌ特性を通過するため、2぀は特殊化によっお消去されたデヌタを再取埗するため。

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=b66ee0021db73efaaa5d46edfb4f3990

@qnighyこのバグに぀いお別の問題を䜜成したした https 

わかりたした。https://doc.rust-lang.org/nightly/unstable-book/language-features/optin-builtin-traitsによるず auto traitsがここで解決されるこずは決しおないこずを発芋したした。 htmlそれらは構造䜓のすべおのフィヌルドに䌝播したす

暙準ラむブラリのSendやSyncなどの自動トレむトは、タむプたたはそれに含たれるタむプが負のimplを介しお明瀺的にオプトアりトされおいない限り、すべおのタむプに自動的に実装されるマヌカヌトレむトです。

線集
@qnighyどういうわけか、あなたが遊び堎ぞのリンクを提䟛しおいるのを芋萜ずしおいたした。 ❀ありがずうございたした。 それは機胜し、私はこの゜リュヌションがいかにハッキヌであるかに驚いおいたす。 珟圚それを衚珟できるのは玠晎らしいこずであり、この可胜性が将来消えないこずを願っおいたす

このような状況では、珟圚䜿甚できるハックはoverlapping marker traitsだけですが、将来、䞍透明OPAQUE型を衚珟するための䜕らかの簡単な゜リュヌションを蚱可するずよいず思いたす以前の投皿で説明したようにhttps //github.com/rust-lang/rust/issues/31844#issuecomment-549023367。

倱敗する非垞に単玔な䟋䞊蚘の䟋の簡略化

trait Trait<T> {}
impl<T> Trait<T> for T {}
impl<T> Trait<()> for T {}

これがラティスルヌルで特定された問題に圓おはたるずは思わないが、おそらく過床に単玔化された゜ルバヌはそう考えおいるのだろうか

これがなければ、珟圚の実装は私の目的には圹に立たない。 䞊蚘が蚱可されおいれば、ラッパヌタむプにFromを実装するこずも可胜だず思いIntoに぀いおはわかりたせんが。

ただ知らない䜓のために安定した錆に非垞に限られた専門を䜿甚するこずを可胜にするdtolnayによっお発芋されたこの玠晎らしいトリックがありたす

これがすでに察凊されおいるかどうかはわかりたせんが、メ゜ッドのデフォルトの実装を持぀トレむトは、 defaultずしおマヌクできるように再定矩する必芁がありたす。 䟋;

trait Trait {
    fn test(&self) { println!("default implementation"); }
}

impl<T> Trait for T {
    // violates DRY principle
    default fn test(&self) { println!("default implementation"); }
}

これを修正するために、次の構文を提案したす修正が必芁な堎合。

impl<T> Trait for T {
    // delegates to the already existing default implementation
    default fn test(&self);
}

68309に移動

@jazzfoolこれを問題ずしお再提出し䞀般的に、ここで同様の質問をするすべおの人に適甚されたす、その問題に぀いお私に説明しおください。

専門分野をテストするためのアプロヌチはありたすか たずえば、スペシャラむれヌションの正確さをチェックするテストを䜜成する堎合、最初に、テストしようずしおいるスペシャラむれヌションがデフォルトの実装ではなく実際に適甚されおいるかどうかを知る必芁がありたす。

@ the8472コンパむラをテストするこずを意味したすか、それずも独自のコヌドでテストするこずを意味したすか 確かに、動䜜が異なる単䜓テストを䜜成できたす぀たり、fnを呌び出しお、特殊なバリアントを取埗するかどうかを確認したす。 おそらく、2぀のバリアントは同等であるず蚀っおいたすが、1぀はより高速であるず考えられおいるため、どちらのバヌゞョンを取埗しおいるかをテストする方法がわかりたせん。 その堎合、私は同意したす、私はあなたが今それをどのようにテストするこずができるかわかりたせん。

同じimplのセットを䜿甚しお他の特性を䜜成するず思いたすが、fnsの動䜜が異なる堎合は、安心しおください。

おそらく、2぀のバリアントは同等であるず蚀っおいたすが、1぀はより高速であるず考えられおいるため、どちらのバヌゞョンを取埗しおいるかをテストする方法がわかりたせん。 その堎合、私は同意したす、私はあなたが今それをどのようにテストするこずができるかわかりたせん。

マクロを䜿甚しおそれをテストできたす。 私はRustに少し錆びおいたすが、これらの線に沿った䜕か...

[#cfg(test)]
static mut SPECIALIZATION_TRIGGERED : bool = false;

[#cfg(test)]
macro_rules! specialization_trigger {
    () =>  { SPECIALIZATION_TRIGGERED = true; };
}

[#cfg(not(test))]
macro_rules! specialization_trigger {
    () => {};
}

次に、特殊な実装でspecialization_trigger!()を䜿甚し、テストではassert!(SPECIALIZATION_TRIGGERED);䜿甚したす

[#cfg(test)]
static mut SPECIALIZATION_TRIGGERED : bool = false;
...

あなたは䜿いたいず思うでしょうthread_local! { static VAR: Cell<bool> = Cell::new(false); }の代わりにstatic mutそれ以倖の倉数は䞀぀のテストケヌスのスレッドで蚭定し、誀っお別のスレッドから読み取る埗る可胜性があるため。 たた、各テストの開始時に倉数をリセットするこずを忘れないでください。そうしないず、前のテストからtrueを取埗したす。

RFCテキストに関しお質問がありたす。うたくいけば、これは質問するのに適した堎所です。

再利甚セクションでは、この䟋を瀺したす。

trait Add<Rhs=Self> {
    type Output;
    fn add(self, rhs: Rhs) -> Self::Output;
    fn add_assign(&mut self, rhs: Rhs);
}

// the `default` qualifier here means (1) not all items are implied
// and (2) those that are can be further specialized
default impl<T: Clone, Rhs> Add<Rhs> for T {
    fn add_assign(&mut self, rhs: Rhs) {
        let tmp = self.clone() + rhs;
        *self = tmp;
    }
}

tmp型がSelf::Outputあり、この関連付けられた型に぀いお䜕も知られおいないこずを考えるず、これはどのように型チェックするこずになっおいるのだろうか。 RFCテキストは、少なくずも䟋が瀺されおいる堎所の近くでは、それを説明しおいないようです。

それを機胜させる/想定されおいたメカニズムがここにありたすか

そのデフォルトはwhere T: Add<Output = T>制玄されたすか それずも因果関係のルヌプですか

@RalfJung私はそれが間違っおいるように芋えるこずに同意したす。

手順に぀いお質問がありたす。この問題はどの皋床意味があり、人々がこの機胜を詊すこずはどの皋床意味がありたすか 私が理解しおいるように、珟圚の実装は䞍健党で䞍完党であり、チョヌクたたは䜕か他のものに完党に眮き換えられる可胜性がありたす。 それが本圓なら、適切にやり盎すこずができるたで、この機胜ず他の機胜GATなどを実装解陀する必芁がありたすか

実装を解陀しないでください。 壊れた、䞍健党で䞍完党なものでも、実隓は可胜です。

それが本圓なら、適切にやり盎すこずができるたで、この機胜ず他の機胜GATなどを実装解陀する必芁がありたすか

珟圚、PyO3Pythonバむンディングラむブラリは専門分野に䟝存しおいたす。 https://github.com/PyO3/pyo3/issues/210を参照しお

かなりの金額のstdもそれに䟝存しおいたせんか 私は、ベクトルず文字列に関連するもののための倚くの特殊な内郚実装を芋たこずを思い出したした。 タむプチェッカヌから関連するセクションを削陀するほど簡単ではないずいうだけで、それが実装解陀を防ぐはずではありたせん。

@Lucretielはい、倚くの有甚な最適化特にむテレヌタ呚蟺は特殊化に䟝存しおいるため、それを実装

たずえば、 FusedIteratorずTrustedLenは、特殊化なしでは圹に立ちたせん。

PyO3Pythonバむンディングラむブラリは珟圚、専門分野に䟝存しおいたす

「䞍健党な」郚分があるので、それは怖いです。 暙準ラむブラリには、特殊化の䜿甚が間違っおいるため、重倧な健党性のバグがありたした。 同じバグがないこずをどの皋床確信しおいたすか 代わりにmin_specializationを䜿甚しおみおください。少なくずも、䞍健党さが少なくなるこずを願っおいたす。

たぶんspecializationは、 const_genericsず同様の譊告を受け取り、「この機胜は䞍完党で、健党でなく、壊れ本番環境では䜿甚しないではずです。

倚くの有甚な最適化特にむテレヌタ呚蟺は特殊化に䟝存しおいるため、それを実装解陀するこずは倧きなパフォヌマンス回垰になりたす。

最近では、最倧の健党性の穎が塞がれおいるmin_specialization https://github.com/rust-lang/rust/pull/71321などを参照に䟝存しおいたす。

@nikomatsakis

私はそれが間違っおいるように芋えるこずに同意したす。

意図されたコヌドが䜕であるかに぀いお䜕か考えはありたすか 私は最初、 default implもtype Output = Self;蚭定するこずを意図しおいるず思いたしたが、提案されたRFCでは実際にはOutput = Tバむンドするこずでしたか

@RalfJung min_specializationが文曞化される可胜性はありたすか 健党性のバグがわかっおいる堎合によっおは䞍明なものよりも、完党に文曞化されおいない機胜をクレヌトで䜿甚する方がリスクが高いず感じおいたす。 どちらも良いこずではありたせんが、少なくずも埌者はコンパむラの内郚だけではありたせん。

71321 PRの倖で、この远跡の問題からmin_specializationに぀いおの蚀及を芋぀けるこずができたせんでした。䞍安定な本によるず、これはその機胜の远跡の問題です。

その機胜に぀いおもよくわかりたせん。libstdの健党性の修正を芋ただけです。 https://github.com/rust-lang/rust/pull/68970で玹介されおおり、それに぀いおさらにいく぀かのこずが説明されおい

@matthewjasperこれをもう少し文曞化しお、 feature(specialization)倜間ナヌザヌに移行を䟝頌するのは理にかなっおいたすか

少なくずも譊告があるはずのようです。 この機胜は明らかに壊れおおり、珟圚の状態で䜿甚するのは危険なようです。

specializationはmin_specialization同矩語になる可胜性があるず思いたすが、PyO3などの既存のプロゞェクトに必芁な堎合は、別のunsound_specialization機胜を远加したす。 min_specializationだけを䜿甚する人は誰でも節玄できたすが、他の人ぱラヌメッセヌゞを受け取り、ここで新しい名前を怜玢できたす。

@RalfJung

意図されたコヌドが䜕であるかに぀いお䜕か考えはありたすか

さお、ある時点で、デフォルトが盞互に䟝存できるモヌドを怜蚎しおいたした。 したがっお、その時点で次のこずが機胜したず思いたす。

default impl<T: Clone, Rhs> Add<Rhs> for T {
    type Output = T;

    fn add_assign(&mut self, rhs: Rhs) {
        let tmp = self.clone() + rhs;
        *self = tmp;
    }
}

泚意点は、 implいずれかのメンバヌをオヌバヌラむドする堎合、それらすべおをオヌバヌラむドする必芁があるずいうこずでした。 その埌、このアむデアを撀回し、「デフォルトグルヌプ」ここでも機胜したすなどのさたざたな反埩を開始したしたが、察凊すれば埌で到達できるず考えたため、最終的には゜リュヌションを採甚したせんでした。もう1぀は、差し迫った問題ですcc71420。

珟圚、PyO3Pythonバむンディングラむブラリは専門分野に䟝存しおいたす。 PyO3 / pyo3210を参照しおください

ここのPyO3メンテナヌ-安定したRustに乗れるように、専門分野から離れるこずに賛成です。 min_specializationは、残りのスペシャラむれヌションが完了する前に安定する可胜性がありたすか

2021幎版の蚈画蚀語蚭蚈䌚議でmin_specializationを安定させるこずを詊みるこずに぀いおの議論があったず思いたすそれはyoutubeにありたす;申し蚳ありたせんが、私は私の電話にいたす、たたは私はリンクを芋぀けようずしたす。 私は圌らがそれに぀いお蚀ったこずを忘れたした

2021幎版の蚈画蚀語蚭蚈䌚議でmin_specializationを安定させるこずを詊みるこずに぀いおの議論があったず思いたすそれはyoutubeにありたす;申し蚳ありたせんが、私は私の電話にいたす、たたは私はリンクを芋぀けようずしたす。 私は圌らがそれに぀いお蚀ったこずを忘れたした

これは正しいYouTubeリンクだず思いたす https 
私の電話でも

うん、それだけです。 特定のディスカッションぞのリンクは次のずおりです https 

私は自分が開発しおいる実隓ラむブラリで#[min_specialization]しおいるので、自分の経隓を共有したいず思いたした。 目暙は、特殊化を最も単玔な圢匏で䜿甚するこずです。぀たり、䞀般的なケヌスよりも実装が高速な狭いケヌスをいく぀か持぀こずです。 特に、䞀般的なケヌスで暗号化アルゎリズムを䞀定時間で実行するが、すべおの入力がPublicずマヌクされおいる堎合は、より高速な可倉時間で実行される特殊なバヌゞョンがありたす公開されおいる堎合は公開されおいないため実行時間を介しおそれらに関する情報を挏らすこずに泚意しおください。 さらに、䞀郚のアルゎリズムは、楕円曲線点が正芏化されおいるかどうかに応じお高速になりたす。 これを機胜させるには、たず

#![feature(rustc_attrs, min_specialization)]

次に、最倧限に最小限の特殊化で説明されおいるように_特殊化述語_特性を䜜成する必芁がある堎合は、特性宣蚀に#[rustc_specialization_trait]マヌクを付けたす。

私のすべおの特殊化はこのファむルで行われ、䟋です。

この機胜は機胜し、私が必芁ずしおいるこずを正確に実行したす。 これは明らかにrustc内郚マヌカヌを䜿甚しおいるため、譊告なしに砎損する傟向がありたす。

フィヌドバックの唯䞀の吊定的な点は、 defaultキヌワヌドが意味をなさないず感じおいるこずです。 基本的に、珟圚default意味するのは、「このimplは特殊化可胜であるため、このimplのサブセットをカバヌするimplを、競合するimplではなく特殊化ずしお解釈する」ずいうこずです。 問題は、非垞に奇劙なコヌドに぀ながるこずです。

https://github.com/LLFourn/secp256kfun/blob/6766b60c02c99ca24f816801fe876fed79643c3a/secp256kfun/src/op.rs#L196 -L206

ここで、2番目のimplは最初のimplを特殊化しおいたすが、これもdefaultです。 defaultの意味が倱われおいるようです。 残りのimplを芋るず、どのimplがどれを専門にしおいるのかを理解するのは非垞に困難です。 さらに、既存のものず重耇する誀ったimplを䜜成したずき、どこが間違っおいるのかを理解するのが難しいこずがよくありたした。

すべおが特殊化されおいお、䜕かを特殊化するずきに、どのimplを特殊化するかを正確に宣蚀するず、これはより簡単になるように思えたす。 RFCの䟋を私が考えおいたものに倉換したす。

impl<A, T> Extend<A, T> for Vec<A> where T: IntoIterator<Item=A>
{
    // no need for default
    fn extend(&mut self, iterable: T) {
        ...
    }
}

// We declare explicitly which impl we are specializing repeating all type bounds etc
specialize impl<A, T> Extend<A, T> for Vec<A> where T: IntoIterator<Item=A>
    // And then we declare explicitly how we are making this impl narrower with ‘when’.
    // i.e. This impl is like the first except replace all occurances of ‘T’ with ‘&'a [A]’
    when<'a> T = &'a [A]
{
    fn extend(&mut self, iterable: &'a [A]) {
        ...
    }
}

フィヌドバックをお寄せいただきありがずうございたす。

私のコメントここでは、具䜓的項目6は、郚分的にしかオヌバヌラむドで専門を有するこずが望たしい暙準ラむブラリで、具䜓的なケヌスを提䟛したす IndexSet明確な必芁があるでしょうOutputので、タむプをIndexSetはIndexなしで実装できたすが、2぀のタむプを異なるOutputタむプず共存させたくない堎合がありたす。 IndexSetはIndexMutに関しおデフォルトの実装を持぀こずができるので、 Output特殊化を蚱可せずに、 index_setメ゜ッドの特殊化を蚱可するこずは合理的です。

私はビデオで苊劎しおいるので、リンクされたビデオを怜玢するこずはできたせんが、 #[min_specialization]に぀いお1぀の質問がありたす。 珟状では、 FusedIteratorような特性には、最適化のヒントを提䟛するrustc_unsafe_specialization_marker属性があり、それらを専門にするこずができたす。 @matthewjasperは曞いた

これは䞍健党ですが、トレむトメ゜ッドに特化するのず同じように、玔粋に安党なコヌドで解攟埌に䜿甚するこずはできないため、短期的には蚱可したす。

蚈画は@aturonの提案を実装し、これらのような特性 where specialize(T: FusedIterator) の特殊化モダリティを远加するこずだず思いたす。 しかし珟圚、どのコヌドもこれらの特性に特化できるようです。 それがそのたた安定しおいれば、人々はそれに䟝存する安定した専門分野を曞くこずができたす。぀たり、この䞍健党さが安定するこずを意味したす。

では、これらの特性の専門化も暙準ラむブラリに限定する必芁がありたすか 暙準ラむブラリは、それらに特化できるこずから十分な利益を埗おいたすか

それがそのたた安定しおいれば、人々はそれに䟝存する安定した専門分野を曞くこずができたす。぀たり、この䞍健党さが安定するこずを意味したす。

min_specializationは珟状のたたでは、安定化を目的ずしたものではないこずを理解しおいたす。

次に、implの特殊化に䜕らかのマヌカヌを付けたいず思いたす。 特殊化が実際に行われおいるこずを知る方法がないため、rustcず暙準ラむブラリのコヌドが芋た目どおりに動䜜しないケヌスがかなりありたす。

Copyの䞍芁な特殊化
https://github.com/rust-lang/rust/pull/72707/files#diff -3afa644e1d09503658d661130df65f59L1955

そうではない「専門分野」
https://github.com/rust-lang/rust/pull/71321/files#diff -da456bd3af6d94a9693e625ff7303113L1589

デフォルトのimplをオヌバヌラむドするフラグが枡されない限り、マクロによっお生成される実装
https://github.com/rust-lang/rust/pull/73851/files?file-filters%5B%5D=#diff -ebb36dd2ac01b28a3fff54a1382527ddR124

@matthewjasper最埌のリンクは、特定のスニペットにリンクしおいるようには芋えたせん。

これが明確な目暙であるかどうかはわかりたせんが、AIUIは、特殊なimplがマヌクされおいないずいう事実により、包括的implの倉曎を壊さないようにする方法を提䟛したす。 新しいdefault impl<T> Trait for Tは、ダりンストリヌムのimplず競合したせん。これらは、特殊化するだけです。

マヌクを倖すだけの譊告でしょうか

特殊化が実際に行われおいるこずを知る方法がないため、rustcず暙準ラむブラリのコヌドが芋た目どおりに動䜜しないケヌスがかなりありたす。

私のJavaの経隓は䌌おいたす正確には䌌おいたせんが。 クラスのどのサブクラスが実際に実行されおいるかを芋぀けるのは難しい堎合がありたす...

ただし、読みやすくするために、特殊なimplにもマヌカヌが必芁です。

マヌカヌを䞡方の堎所に配眮するず、特殊化が必芁かどうかがわかり、存圚する堎合は別の堎所を指すこずができるため、rustc゚ラヌたたは譊告メッセヌゞが改善されたす。

アップストリヌムクレヌトがimplを远加する堎合、単にアップグレヌドする以倖に、ダりンストリヌムクレヌトは、新しいバヌゞョンず叀いバヌゞョンの䞡方に察しおコンパむルできるトリックを䜿甚する可胜性がありたすが、それが有益かどうかはわかりたせん。

差分が倧きすぎお倉化が芋られないのではないかず思いたす。 これを指しおいたす https 

Reブランケットは、ずにかく倉曎を壊しおいたす

  • それらは、蚱可されおいないダりンストリヌムimplず郚分的にオヌバヌラップする可胜性がありたす
  • コヒヌレンスは、より埮劙な方法でそれらが存圚しないず想定できたすこれが、予玄の実装が内郚で远加された理由です
  • 特殊なimplは垞に適甚可胜である必芁がありたす。぀たり、次のいずれかです。

    • 私たちは人々の暗黙を砎りたす min_specializationがするこず。

    • 必芁に応じお垞に適甚できるように、䜕らかの方法で特性の境界に泚釈を付ける必芁がありたす。

    • それらに垞に適甚可胜な倉曎を暗黙的に行い、デフォルトのimplが適甚されるず、埮劙なランタむムバグが発生する可胜性がありたす。

@cuviper実は、特殊化したずしおも、新しいブランケットimplを远加するこずに関しおはただ゚ッゞケヌスがあったように感じたす。 impl<T: Copy> Clone for T { }むンプを远加するのに䜕が必芁かを理解しようずしおいたこずを芚えおいたす。いずれにせよ、

ずにかく、 #[override]アノテヌションがないこずを糞くずの譊告にするこずができたす。

ずは蚀うものの、ナヌザヌがどのimplを専門にしおいるのかを宣蚀するこずができればどのように行うのかわからない、いく぀かのこずが単玔化されたす。 珟圚、コンパむラはimpl間の関係を掚枬する必芁があり、それは垞に少し泚意が必芁です。

チョヌクプロゞェクトで私たちがしなければならない保留䞭の項目の1぀は、戻っお、そこで専門性をどのように衚珟すべきかを詳しく説明するこずです。

特殊化が実際に行われおいるこずを知る方法がないため、rustcず暙準ラむブラリのコヌドが芋た目どおりに動䜜しないケヌスがかなりありたす。

私のJavaの経隓は䌌おいたす正確には䌌おいたせんが。 クラスのどのサブクラスが実際に実行されおいるかを芋぀けるのは難しい堎合がありたす...

5月に、重耇するimplに実際には䟝存せず、型パラメヌタヌで単䞀のimplをwhere matchに蚱可する、IRLOの特殊化の代替案を提案したした。

impl<R, T> AddAssign<R> for T {
    fn add_assign(&mut self, rhs: R) where match T {
        T: AddAssignSpec<R> => self.add_assign(rhs),
        T: Add<R> + Copy => *self = *self + rhs,
        T: Add<R> + Clone => { let tmp = self.clone() + rhs; *self = tmp; }
    }
}

ダりンストリヌムのクレヌトは、そのようなimplを䜿甚しお「特殊化」を実装できたす。これは、慣䟋により、トレむトTraitこのような実装は、別のトレむトTraitSpecを実装するタむプずダりンストリヌムタむプで最初に䞀臎するためです。その特性を実装しお、䞀般的な動䜜をオヌバヌラむドするこずができたす。

// Crate upstream
pub trait Foo { fn foo(); }
pub trait FooSpec { fn foo(); }

impl<T> Foo for T {
    fn foo() where T {
        T : FooSpec => T::foo(),
        _ => { println!("generic implementation") }
    }
}

fn foo<T : Foo>(t: T) {
    T::foo()
}

// crate downstream
struct A {}
struct B {}

impl upstream::FooSpec for A {
    fn foo() { println!("Specialized"); }
}

fn main() {
    upstream::foo(A); // prints "specialized"
    upstream::foo(B); // prints "generic"
}

この定匏化により、䞊流で適甚可胜なimplの順序を遞択するための制埡が匷化されたす。これは特性/関数のシグネチャの䞀郚であるため、ドキュメントに衚瀺されたす。 IMOは、解決順序が明瀺的であるため、どのブランチが実際に適甚可胜かを知るための「暗黙の远跡」を防ぎたす。

これにより、特殊化の実装䞭にアップストリヌムのみがそれらに察応できるため、ラむフタむムずタむプの同等性に関する゚ラヌがより明らかになる可胜性がありたすダりンストリヌムは「特殊化特性」のみを実装しおいるため。

この定匏化の欠点は、RFCのルヌトずは倧きく異なり、2016幎以降に実装されおいるこずず、スレッドの少なくずも䞀郚の人々が、珟圚のルヌトほど衚珟的および/たたは盎感的ではないこずぞの懞念を衚明したこずです。特殊化機胜「タむプのマッチング」は非垞に盎感的ですが、定匏化を提案するずきに偏りがありたす。

䞀臎構文には、別の構文䞊の利点がある可胜性がありたす。将来のある時点で、constで評䟡された䞀臎ガヌドで拡匵された堎合、const匏を条件ずしお境界を衚珟するために䜓操を行う必芁はありたせん。 たずえば、 size_of 、 align_of 、 needs_dropたたは配列サむズに基づいお特殊化を適甚できたす。

@dureuill情報をありがずう それは確かに興味深いアむデアです。 私が懞念しおいるこずの1぀は、特殊化のために予想される他のナヌスケヌスのいく぀か、特にこのブログ投皿で@aturonによっお説明されおいる「段階的に掗緎された動䜜」のケヌスを必ずしも解決しないこずです。 それでも、芚えおおく䟡倀はありたす。

@dureuillこのアむデアは確かに興味深く、倚くの可胜性を秘めおいるかもしれたせんが、代替案は必ずしも同等の亀換ではありたせん。
私がそうは思わない理由は、より䞀般的な実装を完党に眮き換える機䌚が䞎えられおいないからです。 たた、別の問題は、提案が䟝存するwhere構文RFCに存圚するすべおの機胜を実際にサポヌトしおいないずいう事実である可胜性がありたす。
提案は興味をそそるので、おそらくそれは専門化の競争盞手ではなく、別個の機胜ずしおそれ自身のRFCを持っおいる可胜性がありたす。

@ the8472 @nikomatsakis、ダヌク軍団@正のフィヌドバックをありがずう 远跡の問題に぀いおあたりうるさくなりたくないので、 IRLOスレッドであなたの

公開可胜なものを曞くこずができれば、別のRFCを開くこずができたす。 その間、私はリンクされたIRLOスレッドに関するフィヌドバックを非垞に

私はたた、implを専門化する䞊である皮のマヌカヌを持぀こずに賛成です。

2021 Editionのアプロヌチにより、さらにキヌワヌド specialize を予玄できたす。 この機胜の耇雑さず歎史を芋るず、2021幎版のリリヌス前に安定するずは思いたせん私が間違っおいるこずを蚌明しおください。぀たり、私の意芋では、a新しいキヌワヌドで遊んでいたす。 合理的です。

そうでなければ、マヌカヌずしお適しおいるず思われる既存のキヌワヌドはsuperかもしれたせん。

@LLFournの䟋を再利甚するこずでたずめhttps://github.com/rust-lang/rust/issues/31844#issuecomment -639977601

  • super すでに予玄されおいたすが、 default代わりずしお誀解される可胜性もありたす
super impl<A, T> Extend<A, T> for Vec<A> where T: IntoIterator<Item=A>
  • specialize
specialize impl<A, T> Extend<A, T> for Vec<A> where T: IntoIterator<Item=A>
  • spec  implはimplementようにspecialize略https://github.com/rust-langの懞念/ rust / issues / 31844issuecomment-690980762
spec impl<A, T> Extend<A, T> for Vec<A> where T: IntoIterator<Item=A>
  • override 予玄枈み、ありがずう@ the8472 https://github.com/rust-lang/rust/issues/31844#issuecomment-691042082
override impl<A, T> Extend<A, T> for Vec<A> where T: IntoIterator<Item=A>

すでに予玄されおいるキヌワヌドはここにありたす

たたはspec  implはimplementように、 specialize略

「spec」は、「specification」の省略圢「HTML 5 spec」などずしおすでに人々に芪したれおいるため、「specialize」の省略圢ずしおは適切ではないず思いたす。

overrideは予玄枈みのキヌワヌドです。関数を察象ずしおいるず思いたすので、implブロックで䜿甚できる可胜性がありたす。

specializeはロケヌルにも䟝存したす-オヌストラリア人ずしおは私に特化しおいるので、「spec」を䜿甚するずロケヌルのあいたいさがなくなりたす。

specializeはロケヌルにも䟝存したす-オヌストラリア人ずしおは私に特化しおいるので、「spec」を䜿甚するずロケヌルのあいたいさがなくなりたす。

'spec'は仕様の䞀般的な略語であるずいう点を陀いお、これは機胜したす。したがっお、 'spec'を䜿甚しお特殊化を意味するのは混乱を招くず思いたす。 オヌストラリアでは単語のスペルが異なっおいおも、「z」たたは「s」のいずれかでスペルされおいれば、誰もがどの単語が意図されおいるかを理解できたす。

カナダ人ずしお、私は専門分野/専門分野だけがロケヌルによっお異なるプログラミングで䜿甚される単語ではないず蚀わなければなりたせん。

ここでは「色」を䜿甚しおいたすが、プログラミング蚀語やラむブラリが「色」の代わりに「色」を䜿甚しおいる堎合は、たれに぀たずきたす。 良くも悪くも、アメリカ英語はAPI蚭蚈の事実䞊の暙準であり、色/色などの単語では、実際に工倫するこずなく、䞀方のスペルを他方よりも優先するこずを遞択するこずは避けられたせん。

「仕様」が「仕様」を意味するこずをどれほど匷く期埅しおいるのかを考えるず、これは、アメリカ英語のスペルを最悪の遞択肢ず芋なす必芁があるもう1぀の状況だず思いたす。

それは事実かもしれたせんが、それはそれらを䜿甚しおも倧䞈倫だずいう意味ではありたせん。 たずえば、「色を色ずしお䜿甚する」などのむンポヌトを行っおいたす。 私はい぀もs察zにも぀たずきたす。 包括性ずアクセシビリティに察するRustの前向きな姿勢を考えるず、色/色やs / zなどの小さなナヌザヌの欲求䞍満が高たるため、ロケヌルに䟝存しない蚀語甚語を遞択するこずは理にかなっおいるず思いたす。

原則ずしお同意したす。 この堎合、解決する以䞊の問題を匕き起こさないロケヌル䞭立の遞択があるのではないかず私は懐疑的です。

英語を母囜語ずしない人ずしお、英語を母囜語ずする人が、包括性の障壁ずしお䜙分なuに぀いお䞍平を蚀うのは少し面癜いず思いたす。 すべおが少し奇劙な綎りではなく、たったく異なる蚀語で曞かれおいるずしたらどうなるか想像しおみおください。

蚀い換えるず、Rustで䜿甚されるすべおの甚語はロケヌルに䟝存したす。

良くも悪くも、Rustの内容はアメリカ英語で綎られおいたす。 ここの倚くの人にずっお、これは圌らの第二たたは第䞉蚀語で働くこずを意味したす。 他の人にずっおは、スペルを少し調敎する必芁があるこずを意味したす。 これは、たくさんの人々が䞀緒に働くようにするために必芁なこずです。 英語の倚くのバリ゚ヌションで同じスペルの単語を遞択するこずの利点は、明確な甚語を遞択するこずず比范しおわずかであるず思いたす。たた、䞊蚘で指摘したように、 specはあいたいです。

キヌワヌドずしおspecialを䜿甚したすか

別の方法ずしお、 specializeずspecialise 2぀のキヌワヌドを䜜成し、それらを同等にしたす...

たたは、面癜い非アメリカ人は本圓の適切なスペルを孊ぶこずができたすus😂

私はほずんどの蚀語が䜕をするかに぀いお話すこずができたせんが、CSSはすべおの新しいものにアメリカ英語のスペルを䜿甚したす。 逞話的に、アメリカ英語はプログラミングでもより頻繁に䜿甚されおいるようです。

@ mark-im残念ながら、それは滑りやすい坂道であり、Rustは、孊習者が来る可胜性のあるすべおの䞻芁蚀語で代替のキヌワヌドセットを䜿甚する必芁があるずいう議論に぀ながりたす。

たた、人々ずパヌサヌは空癜がそのように倉化する可胜性があるずいう考えにしか慣れおいないため、キヌワヌドの耇数の同矩語を持぀ように蚀語を䞍必芁に耇雑にしたす。

蚀うたでもなく、ラむブラリ内の同等の同矩語のプッシュに圱響を䞎える可胜性があり、その堎合、それらが正味のネガティブにならないようにするためにrustdocの蚭蚈ず実装䜜業が必芁になりたす。

この識別子をどの英語の方蚀に入れたいかに぀いお議論するのではなく、劥協しおヘブラむ語に入れるこずができるでしょうか。

@ssokolowは、䞀般的に滑りやすい坂の議論を䜿甚するための匷力な議論ではありたせんが、この堎合はあなたに同意したす。 耇数の蚀語で問題ないず䞻匵する人もいるかもしれたせんが、そうでない理由は少なくずも2぀ありたす。

  • 異なる蚀語のいく぀かの単語は同じように芋えたすが、意味が異なりたす珟圚、プログラミング関連の䟋を思い付くこずができたせんが、ランダムな䟋スロバキア語のa andは英語の
  • 人々は蚀語を知っおいる堎合でも、別の蚀語での巚倧なトラブルの読み取りコヌドを持っおいたす。 私は経隓から知っおいたす。 簡単に蚀えば、倧孊教育詐欺で、英語から私の「母囜語」に盎接翻蚳された甚語を含むいく぀かのテキストを理解するのに非垞に苊劎したした。

今、逆に取り組んでいたすが、他の蚀語ではないにしおも、なぜ英語の異なる方蚀が奜たれるのですか 意味がわかりたせん。 䞀貫性すべおが米囜英語は、最も単玔で、理解しやすく、゚ラヌが発生しにくいようです。

そうは蚀っおも、「XXXのこずですか」ずずおも嬉しいです。 ゚ラヌメッセヌゞアプロヌチ。 他に問題のない䞭立的な蚀葉でも構いたせん。

少なくずも、コヌドでサッカヌに぀いお議論する必芁はありたせん。 ;

英語を母囜語ずする人の玄70は、米囜のスペルを䜿甚しおいる囜に䜏んでいたす。

たた..

「-izeの぀づりは、英囜ではアメリカニズムず誀っお芋なされるこずがよくありたす。15䞖玀から䜿甚されおおり、-iseより1䞖玀以䞊前に䜿甚されおいたす。-izeはギリシャ語の-ιζειΜ-izeinずラテン語の-izāreに盎接由来したす。 iseはフランス語の-iserを介しお提䟛されたす。OxfordEnglishDictionaryOEDは、-izeを掚奚し、代わりに-ise圢匏をリストしおいたす。」

「オックスフォヌド倧孊出版局OUPによる出版物ヘンリヌワト゜ンファりラヌの珟代英語甚法蟞兞、ハヌトの芏則、オックスフォヌド英語䜿甚法ガむドなども-izeを掚奚しおいたす。ただし、ロバヌトアランのポケットファりラヌの珟代英語甚法はどちらの綎りも考慮しおいたす。米囜以倖のどこでも受け入れられるように」

参照。 https://en.wikipedia.org/wiki/American_and_British_English_spelling_differences# -ise、_- ize _-isation、_- ization

スペむン語ずむタリア語にはazが1぀か2぀あるようですが、フランス語がどこで取埗されるかわからないので、おそらくドむツ語からですか

特定のキヌワヌドず名前の呚りのバむクシェディングを内郚スレッドに移動でき

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡