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)
  • [] ๊ด€๋ จ const์™€ ํ†ตํ•ฉ
  • [] ๊ฒฝ๊ณ„๊ฐ€ ํ•ญ์ƒ ์ œ๋Œ€๋กœ ์ ์šฉ๋˜์ง€๋Š” ์•Š์Œ (https://github.com/rust-lang/rust/issues/33017)
  • [] ๋ถ€๋ชจ์—๊ฒŒ default ๋ฉค๋ฒ„๊ฐ€์—†๋Š” ๊ฒฝ์šฐ ๋นˆ impls๋ฅผ ํ—ˆ์šฉํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ? https://github.com/rust-lang/rust/issues/48444
  • [] "ํ•ญ์ƒ ์ ์šฉ ๊ฐ€๋Šฅ"impls 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 ๊ธฐ๋Šฅ์€ ๋ถˆ๊ฑด์ „ํ•ฉ๋‹ˆ๋‹ค . ์ฆ‰, 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)]

๊ทธ๋Ÿฐ ๋‹ค์Œ ์ตœ๋Œ€ ์ตœ์†Œ ์ „๋ฌธํ™”์— ์„ค๋ช… ๋œ๋Œ€๋กœ _specialization predicate_ ํŠน์„ฑ์„ ๋งŒ๋“ค์–ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ํŠน์„ฑ ์„ ์–ธ์„ #[rustc_specialization_trait] ํ•ฉ๋‹ˆ๋‹ค.

๋‚ด ๋ชจ๋“  ์ „๋ฌธํ™”๋Š” ์ด ํŒŒ์ผ ์—์„œ ์ˆ˜ํ–‰๋˜๋ฉฐ ์—ฌ๊ธฐ ์— ์ „๋ฌธํ™” ์ˆ ์–ด ํŠน์„ฑ

์ด ๊ธฐ๋Šฅ์€ ์ž‘๋™ํ•˜๋ฉฐ ํ•„์š”ํ•œ ์ž‘์—…์„ ์ •ํ™•ํžˆ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ถ„๋ช…ํžˆ rustc ๋‚ด๋ถ€ ๋งˆ์ปค๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ๊ฒฝ๊ณ ์—†์ด ๊นจ์ง€๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.

์œ ์ผํ•œ ๋ถ€์ •์ ์ธ ํ”ผ๋“œ๋ฐฑ์€ default ํ‚ค์›Œ๋“œ๊ฐ€ ๋ง์ด๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ณธ์งˆ์ ์œผ๋กœ default ๊ฐ€ ํ˜„์žฌ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์€ "์ด impl์€ ํŠน์ˆ˜ํ™” ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ ์ถฉ๋Œํ•˜๋Š” impl์ด ์•„๋‹ˆ๋ผ์ด ํ•˜๋‚˜์˜ ํ•˜์œ„ ์ง‘ํ•ฉ์„ ํฌํ•จํ•˜๋Š” impl์„ ํ•ด์„ํ•ฉ๋‹ˆ๋‹ค"์ž…๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ๋งค์šฐ ์ด์ƒํ•œ ์ฝ”๋“œ๋กœ ์ด์–ด์ง„๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

์—ฌ๊ธฐ์„œ ๋‘ ๋ฒˆ์งธ impl์€ ์ฒซ ๋ฒˆ์งธ๋ฅผ ์ „๋ฌธํ™”ํ•˜๊ณ  ์žˆ์ง€๋งŒ default ์ด๊ธฐ๋„ํ•ฉ๋‹ˆ๋‹ค. default ์˜ ์˜๋ฏธ๊ฐ€ ์†์‹ค ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€ impls๋ฅผ ์‚ดํŽด๋ณด๋ฉด ์–ด๋–ค 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๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์—ด์–ด ๋‘๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๋” ๋‚˜๋น ์ง‘๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋ช…๋ฐฑํ•œ ๋ถ€์ •์ ์ธ ์ถ”๋ก ์„ ๊ฒฐ์ฝ” ์ข‹์•„ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ „์ฒด ๋ถ€์ •์ ์ธ ์ถ”๋ก  ์ „๋ฌธํ™”๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์ข‹์€ ํƒ€ํ˜‘์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ด impl์ด ๊ตฌํ˜„ ๋œ ์ „๋ฌธํ™”์™€ ํ•จ๊ป˜ ํ—ˆ์šฉ๋˜์–ด์•ผํ•ฉ๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ๋‚ด๊ฐ€ ๋ญ”๊ฐ€๋ฅผ ๋†“์น˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?
http://is.gd/3Ul0pe

์ด๊ฒƒ๊ณผ ๋™์ผํ•˜๊ฒŒ ์ปดํŒŒ์ผ ๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ–ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค : http://is.gd/RyFIEl

๊ด€๋ จ ์œ ํ˜•์ด ๊ด€๋ จ๋˜์–ด์žˆ์„ ๋•Œ ๊ฒน์นจ์„ ๊ฒฐ์ •ํ•˜๋Š” ๋ฐ ๋ช‡ ๊ฐ€์ง€ ๋‹จ์ ์ด์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ปดํŒŒ์ผ๋ฉ๋‹ˆ๋‹ค : http://is.gd/JBPzIX , ๋ฐ˜๋ฉด์ด ๋™์ผํ•œ ์ฝ”๋“œ๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค : http://is.gd/0ksLPX

๋‹ค์Œ์€ ์ „๋ฌธํ™”๋กœ ์ปดํŒŒ์ผ ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

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 ๊ตฌํ˜„ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ถฉ๋Œ์ด ์—†์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

ํ—‰

์ฒ˜์Œ ๋‘ ๊ฐ€์ง€ ์˜ˆ๋ฅผ ์‚ดํŽด๋ณผ ์‹œ๊ฐ„์ด์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ ๋‚ด ๋ฉ”๋ชจ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ 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>,

๋ฌธ์ œ๋Š” ์ด๋Ÿฌํ•œ impls๊ฐ€ ๊ฒน์น˜์ง€ ๋งŒ ์–ด๋Š ๊ฒƒ๋„ ๋‹ค๋ฅธ ๊ฒƒ๋ณด๋‹ค ๋” ๊ตฌ์ฒด์ ์ด์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  • ๋‹น์‹ ์€ ์ž ์žฌ์ ์œผ๋กœ ๊ฐ€์งˆ ์ˆ˜ T: FromSql<ST, DB> ๊ฒฝ์šฐ T (๊ฐ€ ์ฒ˜์Œ IMPLํ•˜์ง€๋งŒ ๋‘ ๋ฒˆ์งธ ์ผ์น˜ํ•˜๋„๋ก) ํ•œ ์Œ์€ ์•„๋‹ˆ๋‹ค.
  • ์ž ์žฌ์ ์œผ๋กœ (T, U) ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ :

    • T: FromSqlRow<ST, DB> ,

    • U: FromSqlRow<SU, DB> ,ํ•˜์ง€๋งŒ _not_

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

    • (๊ทธ๋ž˜์„œ ๋‘ ๋ฒˆ์งธ impl์€ ์ผ์น˜ํ•˜์ง€๋งŒ ์ฒซ ๋ฒˆ์งธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค)

  • ๋‹ค์Œ๊ณผ ๊ฐ™์€ (T, U) ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‘ ๊ฐœ์˜ impl์ด ๊ฒน์นฉ๋‹ˆ๋‹ค.

    • T: FromSqlRow<ST, DB>

    • U: FromSqlRow<SU, DB>

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

์ด๊ฒƒ์ด ๊ฒฉ์ž impls๊ฐ€ ํ—ˆ์šฉํ•˜๋Š” ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค. ๊ฒน์น˜๋Š” ๊ฒฝ์šฐ์— ๋Œ€ํ•ด ์„ธ ๋ฒˆ์งธ impl์„ ์ž‘์„ฑํ•˜๊ณ  ์–ด๋–ป๊ฒŒํ•ด์•ผํ•˜๋Š”์ง€ ๋งํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๋˜๋Š” ๋ถ€์ •์ ์ธ ํŠน์„ฑ impls๋Š” ๊ฒน์นจ์„ ๋ฐฐ์ œํ•˜๊ฑฐ๋‚˜ ๊ฐ€๋Šฅํ•œ ์ผ์น˜๋ฅผ ์กฐ์ •ํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณต ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ 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: FromSqlRow<ST, DB> T ๊ฐ€ Option<U> ๊ฐ€ ์•„๋‹Œ T ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (์ฒซ ๋ฒˆ์งธ impl๊ณผ ์ผ์น˜ํ•˜์ง€๋งŒ ๋‘ ๋ฒˆ์งธ๋Š” ์•„๋‹˜).
  • ๋‹น์‹ ์€ ๊ฐ€์งˆ ์ˆ˜ Option<T> ๋“ฑ์ด T: Queryable<ST, DB> ํ•˜์ง€๋งŒ Option<T>: FromSqlRow<Nullable<ST>, DB>

์•ˆ๋…•ํ•˜์„ธ์š”.

๊ตฌํ˜„ ์ถฉ๋Œ์„ ์–ธ๊ธ‰ํ•˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์™€ ํ•จ๊ป˜ ์ปดํŒŒ์ผ์ด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. &str ๋Š” FromStr ๊ตฌํ˜„ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ถฉ๋Œ์ด ์—†์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋ณด์ˆ˜์ ์œผ๋กœ &str ๊ฐ€ ์•ž์œผ๋กœ FromStr ๋ฅผ ๊ตฌํ˜„ํ•  ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ์˜ˆ์ œ์—์„œ๋Š” ์–ด๋ฆฌ์„์€ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ ์šฐ๋ฆฌ๋Š” ํ•ญ์ƒ ์ƒˆ impl์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์ด๋Ÿฌํ•œ impl์„ ์ถ”๊ฐ€ ํ•  ๋•Œ ๋‹ค์šด ์ŠคํŠธ๋ฆผ ์ฝ”๋“œ๊ฐ€ ์†์ƒ๋˜์ง€ ์•Š๋„๋ก ๋ณดํ˜ธํ•˜๋ ค๊ณ ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋ณด์ˆ˜์  ์ธ ์„ ํƒ์ด๋ฉฐ ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ๊ธด์žฅ์„ ํ’€๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ ๋ฐฐ๊ฒฝ์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋‘ ๊ฐ€์ง€ ๊ฒฝ์šฐ๋ฅผ ๋ช…ํ™•ํžˆ ํ•ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ์™„์ „ํžˆ ๋ง์ด๋ฉ๋‹ˆ๋‹ค.

2016 ๋…„ 3 ์›” 22 ์ผ ํ™”์š”์ผ ์˜คํ›„ 6:34 Aaron Turon [email protected] ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ผ์Šต๋‹ˆ๋‹ค.

@SergioBenitez https://github.com/SergioBenitez

๊ตฌํ˜„ ์ถฉ๋Œ์„ ์–ธ๊ธ‰ํ•˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์™€ ํ•จ๊ป˜ ์ปดํŒŒ์ผ์ด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. ๋…ธํŠธ
& str์€ FromStr์„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ถฉ๋Œ์ด ์—†์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ & str์„ ๋ณด์ˆ˜์ ์œผ๋กœ ๊ฐ€์ •ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์•ž์œผ๋กœ FromStr์„ ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋ฆฌ์„์€ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ ์šฐ๋ฆฌ๋Š” ํ•ญ์ƒ ์ƒˆ๋กœ์šด impls๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ 
์ด๋Ÿฌํ•œ 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 Sergio Benitez [email protected]
์ผ๋‹ค :

@aturon https://github.com/aturon

๋ฌธ์ œ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ & str์„ ๋ณด์ˆ˜์ ์œผ๋กœ ๊ฐ€์ •ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์•ž์œผ๋กœ FromStr์„ ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์–ด๋ฆฌ์„์€ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ ์šฐ๋ฆฌ๋Š” ํ•ญ์ƒ ์ƒˆ๋กœ์šด impl์„ ์ถ”๊ฐ€ํ•˜๊ณ 
์ด๋Ÿฌํ•œ impl์„ ์ถ”๊ฐ€ ํ•  ๋•Œ ๋‹ค์šด ์ŠคํŠธ๋ฆผ ์ฝ”๋“œ๊ฐ€ ์ค‘๋‹จ๋˜์ง€ ์•Š๋„๋ก ๋ณดํ˜ธํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์ •ํ™•ํžˆ ์ „๋ฌธํ™”๊ฐ€ ํ•ด๊ฒฐํ•˜๋ ค๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๊นŒ? ์™€
์ „๋ฌธํ™”ํ•˜๋ฉด FromStr์˜ ๊ตฌํ˜„์ด
for & str์€ ๋ฏธ๋ž˜์— ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
& str์— ๋Œ€ํ•œ ํŠน์„ฑ์ด ์šฐ์„ ํ•ฉ๋‹ˆ๋‹ค.

โ€”
๋‹น์‹ ์ด ์–ธ๊ธ‰ ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ฑฐ๋‚˜ GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/rust-lang/rust/issues/31844#issuecomment -200097995

"๊ธฐ๋ณธ"ํŠน์„ฑ ํ•ญ๋ชฉ์ด ์ž๋™์œผ๋กœ default ๊ฐ„์ฃผ๋˜๋Š” ๊ฒƒ์€ ํ˜ผ๋ž€์Šค๋Ÿฌ์›Œ ๋ณด์ž…๋‹ˆ๋‹ค. impl ์™„ํ™”์™€ ํ•จ๊ป˜ Haskell๊ณผ ๊ฐ™์€ ํŠน์„ฑ์— ๋Œ€ํ•œ ๋‘ ๊ฐ€์ง€ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ๋ชจ๋‘ ์›ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ default ์ฒ˜๋Ÿผ ์‰ฝ๊ฒŒ grep ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. default ํ‚ค์›Œ๋“œ๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ๊ธฐ๋ณธ ๊ตฌํ˜„์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ ต์ง€ ์•Š์ง€๋งŒ ๊ทธ๋Œ€๋กœ ๋ถ„๋ฆฌ ํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์–ธ์–ด๋ฅผ ๋ช…ํ™•ํžˆํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์ด๋Ÿฌํ•œ "๊ธฐ๋ณธ"ํŠน์„ฑ ํ•ญ๋ชฉ์„ ๋ฌธ์„œ์—์„œ "ํŠน์„ฑ ์ œ์•ˆ"ํ•ญ๋ชฉ์œผ๋กœ ์ด๋ฆ„์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ  # 32999 (์ฃผ์„) : ๊ฒฉ์ž ๊ทœ์น™ (๋˜๋Š” ๋ถ€์ •์  ์ œ์•ฝ ์กฐ๊ฑด ํ—ˆ์šฉ)์„ ์‚ฌ์šฉํ•˜๋ฉด "์ค‘๊ฐ„ ํŠน์„ฑ ์‚ฌ์šฉ"ํŠธ๋ฆญ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋” ์ด์ƒ ํŠน์ˆ˜ํ™”๋ฅผ ๋ฐฉ์ง€ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋ฟก๋ฟก

์™œ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ? ์†์ž„์ˆ˜๋Š” ์ „๋ฌธํ™”๋ฅผ ์‚ฌ์ ์ธ ํŠน์„ฑ์œผ๋กœ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค. ์ ‘๊ทผ ํ•  ์ˆ˜ ์—†๋‹ค๋ฉด ์‚ฌ์ ์ธ ํŠน์„ฑ์„ ์ „๋ฌธํ™” ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

@ arielb1 ์•„. ์ข‹์€ ์ง€์ . ์ œ ๊ฒฝ์šฐ์—๋Š” ๊ทธ ํŠน์„ฑ์ด ์‚ฌ์ ์ธ ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค.

๋‚˜๋Š” "๊ณ ์•„์˜ ์ˆœ๋ฐฉํ–ฅ ํ˜ธํ™˜์„ฑ + ์ผ๊ด€์„ฑ ๊ทœ์น™"์ถ”๋ก ์ด ํŠนํžˆ ํฅ๋ฏธ ๋กญ๊ฑฐ๋‚˜ ์œ ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์™ธ๋ถ€์ธ์€ ์ „๋ฌธํ™” ํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ํŠนํžˆ ์šฐ๋ฆฌ๊ฐ€ ํŠน์ •ํ•œ ์ผ๊ด€์„ฑ ๊ทœ์น™์„ ์ง€ํ‚ค์ง€ ์•Š์„ ๋•Œ.

์žฌ์ •์˜ ๋œ default impl ์— ์•ก์„ธ์Šคํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด ํ…Œ์ŠคํŠธ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Design By Contract ๋ฐ libhoare๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์œ ํ˜• ๊ฒ€์‚ฌ ์ค‘์— ๊ธฐ๋ณธ ๊ด€๋ จ ์œ ํ˜•์˜ ํ”„๋กœ์ ์…˜์„ ํ—ˆ์šฉํ•˜๋ฉด ์ปดํŒŒ์ผ์‹œ ์œ ํ˜• ๋น„ ๊ท ๋“ฑ์„ ์ ์šฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. https://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 '์ฝ”๋ฉ˜ํŠธ์— ๋”ฐ๋ผ ํŽธ์ง‘

@rphmeier ๋Š” CloudFlare๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— Tor ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•ด ํ•ด๊ฒฐ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— is.gd๋ฅผ ํ”ผํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. GitHub๋Š” ์ „์ฒด URL์—์„œ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  play.rust-lang.org๋Š” Tor๋ณด๋‹ค ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

@burdges FWIW play.rust-lang.org ์ž์ฒด๋Š” "Shorten"๋ฒ„ํŠผ์œผ๋กœ is.gd๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์•„๋งˆ๋„ ๋ณ€๊ฒฝ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค : https://github.com/rust-lang/rust-playpen/blob/9777ef59b/static/web.js#L333

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค (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

feture specialization ๊ฐ€์ด๋ฅผ ์ง€์›ํ•˜๋ฉฐ ํ˜„์žฌ ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ๊ตฌํ˜„์ด ์žˆ์Šต๋‹ˆ๊นŒ?

ํ—‰

T: Foo + Bar ๋„ T: Foo + Baz ๋„ ๋‹ค๋ฅธ ๊ฒƒ๋ณด๋‹ค ๋” ์ „๋ฌธํ™”๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฌํ•œ impls๋Š” ํ˜„์žฌ ์ „๋ฌธํ™” โ€‹โ€‹๋””์ž์ธ์—์„œ ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰, T: Foo + Bar + Baz ๊ฐ€์žˆ๋Š” ๊ฒฝ์šฐ ์–ด๋–ค impl์ด "์Šน๋ฆฌ"ํ•ด์•ผํ•˜๋Š”์ง€ ๋ช…ํ™•ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

T: Foo + Bar + Baz ๋Œ€ํ•œ impl์„ _ ๋˜ํ•œ _ ์ œ๊ณตํ•˜์—ฌ ๋ช…ํ™•ํ•˜๊ฒŒ ํ•  ์ˆ˜์žˆ๋Š”๋ณด๋‹ค ํ‘œํ˜„์ ์ธ ์‹œ์Šคํ…œ์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์ƒ๊ฐ์ด ์žˆ์ง€๋งŒ ์•„์ง ์™„์ „ํžˆ ์ œ์•ˆ๋˜์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๋ถ€์ •์ ์ธ ํŠน์„ฑ์ด 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 {
   |> ^

๋†€์ด ํ‹€

๋‚˜๋Š” ์œ„์˜ _should_ ์ปดํŒŒ์ผ์„ ๋ฏฟ๊ณ  ์‹ค์ œ๋กœ ์˜๋„ ํ•œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ํฅ๋ฏธ๋กœ์šด ๋ณ€ํ˜•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

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 ๊ฐ€ ๋ณ„๋„์˜ ํฌ๋ ˆ์ดํŠธ (!)์— ์ •์˜ ๋œ ๊ฒฝ์šฐ ์ž‘๋™ํ•˜์ง€ _ ์•Š๋Š” _, ์ด ์˜ˆ์ œ repo ์ฐธ์กฐ)

๋‚˜๋Š” ๋˜ํ•œ์ด ๋ฌธ์ œ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋“  # 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 ํ…์ŠคํŠธ๋Š” ํ—ˆ์šฉ๋˜์–ด์•ผํ•œ๋‹ค๊ณ  ์ œ์•ˆํ•˜์ง€๋งŒ ํ•ด๋‹น ์˜ˆ์ œ๋Š” ๋ณต์‚ฌ๋ฉ๋‹ˆ๋‹ค.

์ „๋ฌธํ™”๋ฅผ ํ†ตํ•ด ํ˜œํƒ์„๋ฐ›์„ ์ˆ˜์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ๋†€์•˜์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ฒด์ธ์œผ๋กœ ๋ฌถ๋Š” ๊ฒƒ๋ณด๋‹ค ๊ฒฉ์ž ๊ทœ์น™์„ ํƒํ•ด์•ผํ•œ๋‹ค๊ณ  ๊ฐ•๋ ฅํ•˜๊ฒŒ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ž์—ฐ์Šค๋Ÿฝ๊ณ  ๋‚ด๊ฐ€ ํ•„์š”ํ•œ ์œ ์—ฐ์„ฑ์„ ์–ป์„ ์ˆ˜์žˆ๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์ด์—ˆ์Šต๋‹ˆ๋‹ค (afaict).

impl ๋ฐ ๊ฐœ๋ณ„ ํ•ญ๋ชฉ์— ๋Œ€ํ•ด default ์— ๊ฐ”๋‹ค๋ฉด ์–ด๋–ค ํ•ญ๋ชฉ์ด ์žฌ์ •์˜๋˜๋ฉด ๋ชจ๋“  ํ•ญ๋ชฉ์ด ์žฌ์ •์˜๋˜์–ด์•ผํ•œ๋‹ค๊ณ  ๊ฐ•์ œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ด๋ฅผ ํ†ตํ•ด ๋‹ค๋ฅธ ํ•ญ๋ชฉ์˜ ๊ธฐ๋ณธ assoc ์œ ํ˜• (์˜ˆ :)์˜ ์ •ํ™•ํ•œ ์œ ํ˜•์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ถ”๋ก  ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Š” ํ‘œํ˜„๋ ฅ์— ์œ ์šฉํ•œ ํ–ฅ์ƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ์„ ํ—ˆ์šฉํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ? ์š”์†Œ ์œ ํ˜•์ด Copy ์ผ ๋•Œ ArrayVec์ด Copy ์ด๊ณ  ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์†Œ๋ฉธ์ž๊ฐ€ ์žˆ๋„๋ก ์œ ํ˜•์„ ํŠน์ˆ˜ํ™”ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ „๋ฌธํ™”๋กœ ๋Œ€์ฒด ๋œ ๋‚ด๋ถ€ ํ•„๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ์ด๋ฅผ ๋‹ฌ์„ฑํ•˜๋ ค๊ณ ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์ด ์ปดํŒŒ์ผ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ค. ์ฆ‰, A: Copy + Array ๋ฐ”์šด๋“œ (playground์˜ ์ปดํŒŒ์ผ ๊ฐ€๋Šฅํ•œ ์Šค ๋‹ˆํŽซ)์— ์˜ํ•ด ์„ ํƒ๋œ ํ•„๋“œ ์œ ํ˜•์—์„œ 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");

ํŠธ์œ— ๋‹ด์•„ ๊ฐ€๊ธฐ

๋ฌธ์ œ๋Š” ๋‹ค๋ฅธ ๊ธฐ๋ณธ ํ•ญ๋ชฉ์˜ ๊ฐ’์— ์˜์กด ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ์ด 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 ์ „๋ฌธํ™”ํ•˜๊ณ  ์žฌ์ •์˜ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ _not_ clonable ์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์—ฌ๊ธฐ์„œ ๋ช‡ ๊ฐ€์ง€ ๊ฐ€๋Šฅํ•œ ๋‹ต๋ณ€์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ์ค‘ ํ•˜๋‚˜๋Š” default ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ญ๋ชฉ์„ ๊ทธ๋ฃนํ™”ํ•˜์—ฌ ํ•˜๋‚˜๋ฅผ ์žฌ์ •์˜ํ•˜๋Š” ๊ฒฝ์šฐ ๋ชจ๋‘ ์žฌ์ •์˜ํ•ด์•ผํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

์ด๊ฒƒ์€ ๊ดœ์ฐฎ์ง€ ๋งŒ ์•ฝ๊ฐ„ "์˜ค๋ฅธ์ชฝ ๋“œ๋ฆฌํ”„ํŠธ ์œ ๋„"์ž…๋‹ˆ๋‹ค. default ๋„ ์ด๋ฆ„ ์ง€์ • ๋ฒ”์œ„์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. "๋ชจ๋‘ ๋ฌด์‹œ"(ํ˜„์žฌ์™€ ๊ฐ™์ด)์™€ "๋ชจ๋‘ ๋ฌด์‹œ"(ํ•„์š”ํ•œ ๊ฒƒ) ์‚ฌ์ด๋ฅผ ์ „ํ™˜ ํ•  ์ˆ˜์žˆ๋Š” ๋” ๊ฐ„๋‹จํ•œ ๋ณ€ํ˜•์ด์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ๋˜ํ•œ impl Trait ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์–ป์„ ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž์Šต๋‹ˆ๋‹ค. ์•„์ด๋””์–ด๋Š” ์—ฌ๊ธฐ์—์„œ์™€ ๊ฐ™์ด ๋ฉ”์„œ๋“œ์˜ ๋ฐ˜ํ™˜ ์œ ํ˜•์„ ์‚ฌ์šฉ์ž ์ •์˜ ํ•  ๋•Œ ๊ฐ€์žฅ ์ž์ฃผ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ impl Trait ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ํŠน์„ฑ์„ ๋‹ค์‹œ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด :

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

์ด๊ฒƒ์€ ์œ ํ˜•๊ณผ fn์„ ํฌํ•จํ•˜๋Š” ๊ธฐ๋ณธ ๊ทธ๋ฃน์— ๋Œ€ํ•ด ๊ตฌํ˜„ ๋  ๋•Œ ํšจ๊ณผ์ ์œผ๋กœ ์ผ์ข…์˜ ์†๊ธฐ์ž…๋‹ˆ๋‹ค. (์ˆœ์ „ํžˆ impl์—์„œ ๊ทธ๋ ‡๊ฒŒํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์„์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.)

์ถ”์‹ , ๊ท€ํ•˜์˜ ๋ฉ”์‹œ์ง€์— ๋Œ€ํ•œ ๋‹ต๋ณ€์ด ์˜ค๋ž˜ ์ง€์—ฐ๋˜์–ด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.

impl Trait์ด ๋„์›€์ด๋˜์ง€๋งŒ ์–ด๋–ค ํ˜•ํƒœ๋กœ๋“  ํŠธ๋ ˆ์ด ํŠธ ๋ฐ”๋””์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉ ๋˜๋Š” ๊ตฌํ˜„ ๋œ RFC๊ฐ€ ์—†์œผ๋ฏ€๋กœ์ด RFC๋ฅผ ์ฐพ๋Š” ๊ฒƒ์ด ์•ฝ๊ฐ„ ์ด์ƒํ•˜๋‹ค๊ณ  ๋Š๋‚๋‹ˆ๋‹ค.

default impl ๊ธฐ๋Šฅ (๋ชจ๋“  ํ•ญ๋ชฉ์ด default )์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ๊ด€์‹ฌ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๊ฒƒ์— ๋Œ€ํ•œ ๊ธฐ์—ฌ๋ฅผ ์ˆ˜๋ฝ ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

@giannicic ํ™•์‹คํžˆ! ์ž‘์—…์„ ๋ฉ˜ํ† ๋งํ•˜๋Š” ๋ฐ ๋„์›€์„ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ์—ฐ๊ด€๋œ ์œ ํ˜•์ด ํŠน์ˆ˜ํ™”๋˜์–ด์•ผํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ๊ฒฐ๋ก ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋‹ค์Œ์€ ํŠน์ˆ˜ํ™” ๊ฐ€๋Šฅํ•œ ๊ด€๋ จ ์œ ํ˜•์— ๋Œ€ํ•œ ํ•„์š”์„ฑ์„ ๋ณด์—ฌ์ฃผ๋Š” ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๋‹จ์ˆœํ™” ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ปจํ…Œ์ด๋„ˆ ํŠน์„ฑ ๊ฐœ์ฒด ์ปฌ๋ ‰์…˜ ( &trait::Property )์„ ์กฐ์ •ํ•˜๋Š” Foo ์™€ ๊ฐ™์€ ์ผ๋ฐ˜์ ์ธ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. trait::Property ํŠธ๋ ˆ์ด ํŠธ๋Š” Property<T> ( Vec<T> ) ๋ฐ PropertyBits (๋น„ํŠธ ๋ฒกํ„ฐ ์ธ BitVec ์ง€์›) ๋ชจ๋‘์— ์˜ํ•ด ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค.
Foo ์ œ๋„ค๋ฆญ ๋ฉ”์„œ๋“œ์—์„œ ๊ด€๋ จ ํ˜•์‹์„ ํ†ตํ•ด T ๋Œ€ํ•œ ์˜ฌ๋ฐ”๋ฅธ ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ์›ํ•˜์ง€๋งŒ, ํŠน์ˆ˜ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์— ๋Œ€ํ•œ ํฌ๊ด„์  ์ธ impl์„ ๊ฐ–๋Š” ์ „๋ฌธํ™”๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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://github.com/rust-lang/rust/issues/37653์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

๊ฒฉ์ž ๊ทœ์น™์ด ๋‹ค์Œ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๊นŒ?

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) ์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ํŠน์„ฑ์œผ๋กœ ์ด๊ฒƒ์„ ๋ฆฌํŒฉํ† ๋งํ•˜์—ฌ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด์•ผํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฟก๋ฟก

์˜ˆ๋ฅผ ๋“ค์–ด A + C๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•„์•ผํ•˜๋Š” ์ผ๋ถ€ ์กฐํ•ฉ์„ "๊ธˆ์ง€"ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„๋‹ˆ์š”, ์ด๊ฒƒ์€ ๊ฒฉ์ž ๊ทœ์น™์ด ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ์–ด๋–ค ํ˜•ํƒœ ๋‚˜ ์ข…๋ฅ˜์˜ "๋ถ€์ •์  ์ถ”๋ก "์˜ ์˜์—ญ์— ๊ฐ€๊น์Šต๋‹ˆ๋‹ค.

์ปจํ…์ŠคํŠธ : ๋‚˜๋Š” ์ด๊ฒƒ์ด ๋ชจ๋‘ ํŠน์„ฑ ์ธ ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ ๋ชจ์–‘ (ํฌ์ธํŠธ, ํ๋ธŒ, ๋‹ค๊ฐํ˜•, ...)์— ๋Œ€ํ•ด ApproxEqual (Shape, Shape) ํŠน์„ฑ์„ ๊ตฌํ˜„ํ•  ๋•Œ ์ด๊ฒƒ์„ ์›ํ•˜๊ฒŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ตฌํ˜„ ์ถฉ๋Œ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ApproxEqualPoint (Point, Point)์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ํŠน์„ฑ์œผ๋กœ์ด๋ฅผ ๋ฆฌํŒฉํ† ๋งํ•˜์—ฌ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด์•ผํ–ˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ @withoutboats ๋Š” ํŠน์ • ํŠน์„ฑ ์ง‘ํ•ฉ์ด ์ƒํ˜ธ ๋ฐฐํƒ€์ ์ž„์„ ์„ ์–ธ ํ•  ์ˆ˜์žˆ๋Š” "์ œ์™ธ ๊ทธ๋ฃน"์ด๋ผ๋Š” ์•„์ด๋””์–ด๋ฅผ ์žฅ๋ คํ–ˆ์Šต๋‹ˆ๋‹ค (์ฆ‰, ์ตœ๋Œ€ ํ•˜๋‚˜๋งŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Œ). ๋‚˜๋Š” ์ด๊ฒƒ์„ ์—ด๊ฑฐ ํ˜• (์ฆ‰, ํŠน์„ฑ์ด ๋ชจ๋‘ ํ•จ๊ป˜ ์„ ์–ธ ๋จ)๊ณผ ๊ฐ™์€ ๊ฒƒ์œผ๋กœ ์ƒ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์— ๋Œ€ํ•œ ์•„์ด๋””์–ด๋ฅผ ์ข‹์•„ํ•˜๋Š”๋ฐ, ํŠนํžˆ ๋ถ€์ •์ ์ธ ์ถ”๋ก ์˜ ๋” ํ•ด๋กœ์šด ์ธก๋ฉด์„ ํ”ผํ•˜๋Š” ๋ฐ ๋„์›€์ด๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ €๋Š”์ด๋ฉด์—์„œ ๋” ๋งŽ์€ ์ƒ๊ฐ์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ถ€์ •์ ์ธ ์ถ”๋ก ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋–  ๋‹ค๋‹ˆ๋Š” ๋ชจ๋“  "๋ฐ์ดํ„ฐ"๋ฅผ ์š”์•ฝํ•˜๋ ค๋Š” ์ข‹์€ ๊ธ€์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์ด์ œ๋Š” HKT์™€ ์ „๋ฌธํ™” ์‹œ๋ฆฌ์ฆˆ๋ฅผ (๋Œ€๋ถ€๋ถ„) ๋งˆ๋ฌด๋ฆฌ ํ–ˆ์œผ๋ฏ€๋กœ ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@nikomatsakis :

๋”ฐ๋ผ์„œ @withoutboats ๋Š” ํŠน์ • ํŠน์„ฑ ์ง‘ํ•ฉ์ด ์ƒํ˜ธ ๋ฐฐํƒ€์ ์ž„์„ ์„ ์–ธ ํ•  ์ˆ˜์žˆ๋Š” "์ œ์™ธ ๊ทธ๋ฃน"์ด๋ผ๋Š” ์•„์ด๋””์–ด๋ฅผ ์žฅ๋ คํ–ˆ์Šต๋‹ˆ๋‹ค (์ฆ‰, ์ตœ๋Œ€ ํ•˜๋‚˜๋งŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Œ). ๋‚˜๋Š” ์ด๊ฒƒ์„ ์—ด๊ฑฐ ํ˜• (์ฆ‰, ํŠน์„ฑ์ด ๋ชจ๋‘ ํ•จ๊ป˜ ์„ ์–ธ ๋จ)๊ณผ ๊ฐ™์€ ๊ฒƒ์œผ๋กœ ์ƒ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์— ๋Œ€ํ•œ ์•„์ด๋””์–ด๋ฅผ ์ข‹์•„ํ•˜๋Š”๋ฐ, ํŠนํžˆ ๋ถ€์ •์ ์ธ ์ถ”๋ก ์˜ ๋” ํ•ด๋กœ์šด ์ธก๋ฉด์„ ํ”ผํ•˜๋Š” ๋ฐ ๋„์›€์ด๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ €๋Š”์ด๋ฉด์—์„œ ๋” ๋งŽ์€ ์ƒ๊ฐ์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ถ€์ •์ ์ธ ์ถ”๋ก ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋–  ๋‹ค๋‹ˆ๋Š” ๋ชจ๋“  "๋ฐ์ดํ„ฐ"๋ฅผ ์š”์•ฝํ•˜๋ ค๋Š” ์ข‹์€ ๊ธ€์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์ด์ œ๋Š” HKT์™€ ์ „๋ฌธํ™” ์‹œ๋ฆฌ์ฆˆ๋ฅผ (๋Œ€๋ถ€๋ถ„) ๋งˆ๋ฌด๋ฆฌ ํ–ˆ์œผ๋ฏ€๋กœ ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์„ ์ž‘์„ฑํ•˜๋Š” ๋™์•ˆ ์ œ์™ธ ๊ทธ๋ฃน์— ๋Œ€ํ•ด ์ƒ๊ฐํ–ˆ์ง€๋งŒ (์ง€๋‚œ๋‚  ํฌ๋Ÿผ์—์„œ ์–ธ๊ธ‰ํ–ˆ์Šต๋‹ˆ๋‹ค),์ด ํŠน์ • ์˜ˆ์ œ์—์„œ ๋ชจ๋“  ํŠน์„ฑ ๊ตฌํ˜„์ด ๋ฐฐํƒ€์  ์ธ ๊ฒƒ์€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋“ค์ด ์ž‘๋™ ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ์˜ˆ๋Š” Point ๋ฐ Float ํŠน์„ฑ์ž…๋‹ˆ๋‹ค. Float _can_์€ 1D ํฌ์ธํŠธ๊ฐ€ ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ApproxEqualPoint(Point, Point) ๋ฐ ApproxEqualFloat(Float, Float) ๋Š” ๋…ํŠนํ•œ. Square ๋ฐ Polygon ๋˜๋Š” Box | Cube ๋ฐ AABB (์ถ• ์ •๋ ฌ ๊ฒฝ๊ณ„ ์ƒ์ž)์—์„œ "ํŠน์„ฑ ๊ณ„์ธต"์— ์‹ค์ œ๋กœ ๋” ๋ณต์žกํ•œ ์ œ์•ฝ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์•„๋‹ˆ์š”, ์ด๊ฒƒ์€ ๊ฒฉ์ž ๊ทœ์น™์ด ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ์–ด๋–ค ํ˜•ํƒœ ๋‚˜ ์ข…๋ฅ˜์˜ "๋ถ€์ •์  ์ถ”๋ก "์˜ ์˜์—ญ์— ๊ฐ€๊น์Šต๋‹ˆ๋‹ค.

์ ์–ด๋„ ํŠน์ • ์‚ฌ๋ก€๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  unimplemented!() ๋ฅผ ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ •๋„๋ฉด ์ถฉ๋ถ„ํ•˜์ง€๋งŒ, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ unimplemented!() ๊ฐ€์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์ •์ ์œผ๋กœ ํฌ์ฐฉํ•œ๋‹ค๋ฉด ๋” ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค (๊ทธ๋ฆฌ๊ณ ์ด ์‹œ์ ์—์„œ ์šฐ๋ฆฌ๋Š” ๋‹ค์‹œ ๋ถ€์ •์ ์ธ ์ถ”๋ก  ์˜์—ญ์— ์žˆ์Šต๋‹ˆ๋‹ค) .

@gnzlbg lattice ์ „๋ฌธํ™”๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด impl ๊ณตํ™ฉ ์ƒํƒœ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ง€๋งŒ ๊ทธ๋ ‡๊ฒŒํ•œ๋‹ค๋Š” ์ƒ๊ฐ์€ ๋‚˜๋ฅผ ์šธ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค

"์ œ์™ธ ๊ทธ๋ฃน"์˜ ๊ฐœ๋…์€ ์‹ค์ œ๋กœ ๋ถ€์ •์ ์ธ ์ดˆ ํŠน์„ฑ ๊ฒฝ๊ณ„์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ๋„ˆ๋ฌด ์ฒ ์ €ํžˆ ํƒ๊ตฌํ•˜์ง€ ์•Š์€ ํ•œ ๊ฐ€์ง€๋Š” ์—ญ ๊ทน์„ฑ ์ „๋ฌธํ™” ๊ฐœ๋…์ž…๋‹ˆ๋‹ค. ์—ญ ๊ทน์„ฑ์„ ๊ฐ–๋Š” ํŠน์ˆ˜ํ•œ impl์„ ๋œ ์ „๋ฌธํ™” ๋œ impl๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด,์ด ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

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

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋Š”์ง€ ์™„์ „ํžˆ ํ™•์‹ ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ์ „๋ฌธํ™”๊ฐ€ ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ๊ณผ ๋‹คํ˜•์„ฑ์„ ๊ฒฐํ•ฉํ•˜๋Š” ๋ฐฉ์‹์— ๋Œ€ํ•ด Niko๊ฐ€ ์ด๋ฏธ ๊ฐ•์กฐํ•œ ๋ฌธ์ œ์™€ ๊ด€๋ จ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋ถ€์ •์ ์ธ ์ถ”๋ก ๊ณผ ๋ถ€์ •์  ํ‘œํ˜„์— ๋Œ€ํ•œ์ด ๋ชจ๋“  ๋…ผ์˜๋ฅผ ํ†ตํ•ด "์ธ์Šคํ„ด์Šค ์ฒด์ธ"์ด๋ผ๋Š” ์˜ค๋ž˜๋œ Haskell ์•„์ด๋””์–ด ( paper , paper , GHC issue tracker , Rust pre-RFC )๋ฅผ ์˜๊ฐ์˜ ์ž ์žฌ์  ์ธ ์›์ฒœ์œผ๋กœ ๋‹ค์‹œ ๋ถˆ๋Ÿฌ ์™€์•ผํ•œ๋‹ค๊ณ  ๋Š๋‚๋‹ˆ๋‹ค. ๊ทธ๋ฐ–์—.

๋ณธ์งˆ์ ์œผ๋กœ ์•„์ด๋””์–ด๋Š” trait impl์„ ์ž‘์„ฑํ•  ์ˆ˜์žˆ๋Š” ๊ณณ์ด๋ฉด ์–ด๋””์—์„œ๋‚˜ ์ด์ „ ํ•ญ๋ชฉ์— ์ ์šฉํ•ด์•ผํ•˜๋Š” ๋‹ค๋ฅธ impl ๋ฅผ ์ง€์ •ํ•˜๋Š” "else if ์ ˆ"์„ ์›ํ•˜๋Š”๋งŒํผ ์ž‘์„ฑํ•  ์ˆ˜๋„ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์„ ํƒ์ ์ธ ๋งˆ์ง€๋ง‰ "else ์ ˆ"์€ ์Œ์˜ impl์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค (์ฆ‰, Trait ์— ๋Œ€ํ•œ ์ ˆ์ด ์ ์šฉ๋˜์ง€ ์•Š์œผ๋ฉด !Trait ์ ์šฉ๋จ).

์•ˆ๋…•ํ•˜์„ธ์š”.

"์ œ์™ธ ๊ทธ๋ฃน"์˜ ๊ฐœ๋…์€ ์‹ค์ œ๋กœ ๋ถ€์ •์ ์ธ ์ดˆ ํŠน์„ฑ ๊ฒฝ๊ณ„์ž…๋‹ˆ๋‹ค.

๋‚ด ์‚ฌ์šฉ ์‚ฌ๋ก€์— ์ถฉ๋ถ„ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ „๋ฌธํ™”๊ฐ€ ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ๊ณผ ๋‹คํ˜•์„ฑ์„ ๊ฒฐํ•ฉํ•˜๋Š” ๋ฐฉ์‹์— ๋Œ€ํ•ด Niko๊ฐ€ ์ด๋ฏธ ๊ฐ•์กฐํ•œ ๋ฌธ์ œ์™€ ๊ด€๋ จ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ๋“ค์ด ํ’€๋ฆด ์ˆ˜ ์žˆ๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ€์ง€๊ณ  ์‹ถ๋‹ค:

  • ๋‹คํ˜•์„ฑ (polymorphism) : ๋‹ค์–‘ํ•œ ์œ ํ˜•์˜ ์ž‘์—…์— ๋Œ€ํ•œ ๋‹ค์–‘ํ•œ ๊ตฌํ˜„์„ ์ถ”์ƒํ™”ํ•˜๋Š” ๋‹จ์ผ ํŠน์„ฑ
  • ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ : ๊ฐ ์œ ํ˜•์— ๋Œ€ํ•œ ์ž‘์—…์„ ๊ตฌํ˜„ํ•˜๋Š” ๋Œ€์‹  ๋ช‡ ๊ฐ€์ง€ ํŠน์„ฑ์„ ๊ตฌํ˜„ํ•˜๋Š” ์œ ํ˜• ๊ทธ๋ฃน์— ๋Œ€ํ•ด ๊ตฌํ˜„ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
  • ์„ฑ๋Šฅ : ํŠน์ • ์œ ํ˜•์— ๋Œ€ํ•ด ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๊ตฌํ˜„ ๋˜๋Š” ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๊ตฌํ˜„๋ณด๋‹ค ๋” ๊ตฌ์ฒด์ ์ธ ์ œ์•ฝ ์ง‘ํ•ฉ์„ ๊ฐ€์ง„ ์œ ํ˜•์˜ ํ•˜์œ„ ์ง‘ํ•ฉ์„ ์žฌ์ •์˜ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ƒ์‚ฐ์„ฑ : ์ปดํŒŒ์ผ์„ ์œ„ํ•ด 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!

๋˜ํ•œ ๋‚˜์—๊ฒŒ ๋ถ€์ •์ ์ธ impls๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

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

ํ•„์š”์— ๋”ฐ๋ผ impl์„ ์ ์ง„์ ์œผ๋กœ ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ impl์ด์—†๋Š” ์œ ํ˜•์˜ ํŠน์„ฑ์„ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•  ๋•Œ ๋ฉ‹์ง„ ์ปดํŒŒ์ผ๋Ÿฌ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋Š”์ง€ ์™„์ „ํžˆ ํ™•์‹ ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

Niko๋Š” ๋ถ€์ •์ ์ธ ์ถ”๋ก ์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๊ณ  ์–ธ๊ธ‰ํ–ˆ์Šต๋‹ˆ๋‹ค. 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

์ด ๋‘ ๊ฐ€์ง€ ๋‹จ์ˆœํ™”๋Š” ์ „๋ฌธํ™”์™€ ํ•จ๊ป˜ ์œ ํšจ ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์„ฑ๊ณต์ ์œผ๋กœ ํ”ฝ์—…ํ•˜์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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> { ... }

(์ด๊ฒƒ์€ ๋ฐ˜๋ณต๊ธฐ ๋ฐ ๋ฒกํ„ฐ ์ด์™ธ์˜ ๋‹ค๋ฅธ ์ƒํ™ฉ๊ณผ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์ด๊ฒƒ์€ ํ•˜๋‚˜์˜ ์˜ˆ์ผ๋ฟ์ž…๋‹ˆ๋‹ค.)

์˜ค๋Š˜๋‚  ์ด๊ฒƒ์€ ์ปดํŒŒ์ผ๋˜์ง€ ์•Š์œผ๋ฉฐ, tsuris์™€์ด๋ฅผ ๊ฐˆ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ „๋ฌธํ™”๋Š”์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

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

๊ทธ๋Ÿฌ๋‚˜์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ณผ์ •์—์„œ ์ƒ์ž์— ๊ณต๊ฐœ ๊ณ„์•ฝ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. Foo ์˜ ๋ฐ˜๋ณต์ž impl์„ ๋ฎ์–ด ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒํ•˜๋„๋ก ๊ฐ•์š”ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ default ์—†๋Š” ์ง€์—ญ ์ „๋ฌธํ™”์ž…๋‹ˆ๋‹ค.


๋‚ด๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ์งˆ๋ฌธ์€ default ์˜ ์—ญํ• ์ด ์ •ํ™•ํžˆ ๋ฌด์—‡์ธ์ง€์ž…๋‹ˆ๋‹ค. default ์š”๊ตฌํ•˜๋Š” ๊ฒƒ์€ ์›๋ž˜ ๋ช…์‹œ ์„ฑ๊ณผ ์ž์ฒด ๋ฌธ์„œํ™” ์ฝ”๋“œ์— ๋Œ€ํ•œ ์ œ์Šค์ฒ˜์˜€์Šต๋‹ˆ๋‹ค. Rust ์ฝ”๋“œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ถˆ๋ณ€์ด๊ณ  ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น„๊ณต๊ฐœ์ด๋ฉฐ ๊ธฐ๋ณธ์ ์œผ๋กœ ์•ˆ์ „ํ•˜์ง€๋งŒ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ตœ์ข… ์ฝ”๋“œ ์—ฌ์•ผํ•ฉ๋‹ˆ๋‹ค. "๋น„ ๊ถ๊ทน์€"์ „์—ญ ์†์„ฑ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋‹น์‹ ์ด ํ•ญ๋ชฉ์„ ์ „๋ฌธ์œผ๋กœ ํ•  ์ˆ˜ ์•Š๋Š” ํ•œ, ๋‚˜๋Š” ํ•ญ๋ชฉ์„ ์ „๋ฌธ์œผ๋กœ ํ•  ์ˆ˜ ์—†๋‹ค.

default ์š”๊ตฌํ•˜๋Š” ๊ฒƒ์€ ์›๋ž˜ ๋ช…์‹œ ์„ฑ๊ณผ ์ž์ฒด ๋ฌธ์„œํ™” ์ฝ”๋“œ์— ๋Œ€ํ•œ ์ œ์Šค์ฒ˜์˜€์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ [..] ๋‚˜๋Š” ๋‹น์‹ ์ด ์•„์ดํ…œ์„ ์ „๋ฌธํ™”ํ•˜๊ฒŒํ•˜์ง€ ์•Š์œผ๋ฉด ์ „๋ฌธํ™” ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜๋„ ์ •๋ง ๊ทธ๋ ‡๊ฒŒ ๋‚˜๋น ์š”? impl์„ ์ „๋ฌธํ™”ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๋„ ์ข‹์•„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด RFC์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋„ ์ด๋ฏธ ์Œ๋ž€ ํ•œ ์–‘์˜ ์˜ค๋ฒ„๋กœ๋”ฉ๊ณผ ์ƒ์†์„ ์‚ฌ์šฉํ•˜๋Š” C ++ ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ์ž‘์—…ํ•˜๋Š” PTSD ํ”Œ๋ž˜์‹œ๋ฐฑ์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์ด์žˆ๋Š” ์ฝ”๋“œ ์ค„์—์„œ wtf๊ฐ€ ์ง„ํ–‰๋˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฑฑ์ •ํ•ฉ๋‹ˆ๋‹ค. @aturon ์ด ์ „๋ฌธํ™”๋ฅผ ๋ช…์‹œํ•˜๊ณ  ์ž์ฒด ๋ฌธ์„œํ™”ํ•˜๊ธฐ ์œ„ํ•ด

๊ทธ๋ž˜๋„ ์ •๋ง ๊ทธ๋ ‡๊ฒŒ ๋‚˜๋น ์š”? impl์„ ์ „๋ฌธํ™”ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๋„ ์ข‹์•„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๋„ "์–ด์ฉŒ๋ฉด"ํŠนํ™”๋ฅผ ์›ํ•˜๊ณ , ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜์ง€ ์•Š๋Š” ์ข‹์€ ์‚ฌ๋ก€๊ฐ€ ์žˆ๋‹ค๋ฉด ์ด๊ฒƒ์„ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์„ ๋ถˆ๊ฐ€๋Šฅ ํ•˜๊ฒŒ ๋งŒ๋“ค๋ฉด ์•ˆ๋ฉ๋‹ˆ๋‹ค. (์บก์Šํ™”์™€ ์•ฝ๊ฐ„ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ถ€ ๋ฐ์ดํ„ฐ์— ์•ก์„ธ์Šคํ•˜๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ๊ณ  ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๋„ ์›ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต๊ฐœ๋กœ ๊ธฐ๋ณธ ์„ค์ •ํ•˜๋Š” ๋Œ€์‹  ๋ช…์‹œ ์ ์œผ๋กœ _this data_ public์œผ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.)

์ด RFC์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋„ ์ด๋ฏธ PTSD ํ”Œ๋ž˜์‹œ๋ฐฑ์ด ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฑฑ์ •๋ฉ๋‹ˆ๋‹ค ...

๊ทธ๋Ÿฌ๋‚˜์ด ์‚ฌ์–‘์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ์–ด๋–ป๊ฒŒ ์ด๋Ÿฌํ•œ ์ผ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์„๊นŒ์š”?

์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜์ง€ ์•Š๋Š” ์ข‹์€ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค๋ฉด ์ด๊ฒƒ์„ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์„ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒŒํ•ด์„œ๋Š” ์•ˆ๋ฉ๋‹ˆ๋‹ค.

์ข‹์€ ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€์žˆ์„ ๋•Œ๋งˆ๋‹ค ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋Š” ๊ฒƒ์€ ๋ฐ˜๋“œ์‹œ ์ข‹์€ ์ƒ๊ฐ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ํ˜ผ๋ž€์Šค๋Ÿฌ์šด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜์žˆ๋Š” ๊ฒฝ์šฐ๋„ ์•„๋‹™๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜์ด ์‚ฌ์–‘์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ์–ด๋–ป๊ฒŒ ์ด๋Ÿฌํ•œ ์ผ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์„๊นŒ์š”?

foo.bar() ๋ฅผ๋ณด๊ณ  bar() ์„๋ณด๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ • ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ ๋‹น์žฅ ์ผ์น˜ํ•˜๋Š” ์œ ํ˜•์— ๊ตฌํ˜„ ๋œ ๋ฉ”์†Œ๋“œ๋ฅผ ์ฐพ์•˜๊ณ  default ๋กœ ํ‘œ์‹œ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ฐพ๊ณ ์žˆ๋Š” ๋ฉ”์†Œ๋“œ ์ •์˜๊ฐ€ ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @withoutboats '์ œ์•ˆ์œผ๋กœ ์ด๊ฒƒ์€ ๋” ์ด์ƒ ์‚ฌ์‹ค์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋Œ€์‹  ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ๋ฅผ ์‹ค์ œ๋กœ๋ณด๊ณ  ์žˆ๋Š”์ง€ ์ ˆ๋Œ€ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋Œ€์‹  ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ๋ฅผ ์‹ค์ œ๋กœ๋ณด๊ณ  ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์ ˆ๋Œ€ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์ง€์—ญ ์œ ํ˜•์— ๋Œ€ํ•ด ๊ธฐ๋ณธ์ด ์•„๋‹Œ impls์˜ ํŠน์ˆ˜ํ™”๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ํšจ๊ณผ๋ฅผ ์ƒ๋‹นํžˆ ๊ณผ์žฅ ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ตฌ์ฒด์ ์ธ impl์„๋ณด๊ณ  ์žˆ๋‹ค๋ฉด ์˜ฌ๋ฐ”๋ฅธ impl์„๋ณด๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ ์ด ์ƒ์ž์˜ ์ „์ฒด ์†Œ์Šค์— ์•ก์„ธ์Šค ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด impl์ด ์ „๋ฌธํ™”๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ "never"๋ณด๋‹ค ํ›จ์”ฌ ๋นจ๋ฆฌ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•œํŽธ, default ๋ฅผ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ impl์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์œผ๋ฉด ๋ฌธ์ œ๊ฐ€ ๋‚จ์•„ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ฌ๋ฐ”๋ฅธ impl์ด ์‹ค์ œ๋กœ default impl์ด๋ฉด ์ด๊ฒƒ์ด ์˜ฌ๋ฐ”๋ฅธ impl์ธ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์€ ๋™์ผํ•œ ์ƒํ™ฉ์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์ „๋ฌธํ™”๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ด๋Š” ๋งค์šฐ ์ผ๋ฐ˜์ ์œผ๋กœ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค (์˜ˆ๋ฅผ ๋“ค์–ด, ์˜ค๋Š˜๋‚  ๊ฑฐ์˜ ๋ชจ๋“  ToString impl์— ํ•ด๋‹น).

์‚ฌ์‹ค ๋‚˜๋Š” ์ด๊ฒƒ์ด ๋‹ค์†Œ ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ default ๊ทธ๊ฒƒ์„ ํ•ด๊ฒฐํ•œ๋‹ค๊ณ  ํ™•์‹ ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์—๊ฒŒ ํ•„์š”ํ•œ ๊ฒƒ์€ ๋” ๋‚˜์€ ์ฝ”๋“œ ํƒ์ƒ‰ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ rustdoc์€ ํŠธ๋ ˆ์ด ํŠธ impls์™€ ๊ด€๋ จํ•˜์—ฌ ๋งค์šฐ '์ตœ์„ ์˜ ๋…ธ๋ ฅ'์ ‘๊ทผ ๋ฐฉ์‹์„ ์ทจํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์†Œ์Šค์— ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์œผ๋ฉฐ ๋‹ด์š” impls์—์„œ ์ œ๊ณตํ•˜๋Š” impls๋„ ๋‚˜์—ดํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š”์ด ๋ณ€ํ™”๊ฐ€ ์–ด๋–ค ์‹ ์œผ๋กœ๋“  ์Šฌ๋žจ ๋ฉํฌ๋ผ๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ์ง€๋งŒ, ๋” ๋ฏธ๋ฌ˜ํ•œ ๊ณ ๋ ค๊ฐ€ ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ข‹์€ ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€์žˆ์„ ๋•Œ๋งˆ๋‹ค ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋Š” ๊ฒƒ์€ ๋ฐ˜๋“œ์‹œ ์ข‹์€ ์ƒ๊ฐ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ํ˜ผ๋ž€์Šค๋Ÿฌ์šด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜์žˆ๋Š” ๊ฒฝ์šฐ๋„ ์•„๋‹™๋‹ˆ๋‹ค.

์ •ํ™•ํ•ฉ๋‹ˆ๋‹ค. ์ „์ ์œผ๋กœ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ์—ฌ๊ธฐ์„œ ๋‹ค๋ฅธ "์‚ฌ์šฉ์ž"์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋‹น์‹ ์ด ์ž‘์„ฑํ•œ ์ƒ์ž์˜ ์‚ฌ์šฉ์ž์ž…๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ๊ทธ๋“ค์ด ๋‹น์‹ ์˜ ์ƒ์ž์—์„œ ํŠน์„ฑ์„ ์ž์œ ๋กญ๊ฒŒ ์ „๋ฌธํ™”ํ•˜๋Š” ๊ฒƒ์„ ์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค (ํ•ดํ‚ค ๋ฐฉ์‹์œผ๋กœ ์ƒ์ž์˜ ํ–‰๋™์— ์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค). ๋‹ค๋ฅธ ํ•œํŽธ์œผ๋กœ, ์šฐ๋ฆฌ๋Š” ๋‹น์‹ ์ด ๋งํ•˜๋Š” "์‚ฌ์šฉ์ž", ์ฆ‰ ์ƒ์ž ์ž‘์„ฑ์ž์—๊ฒŒ ๋” ๋งŽ์€ ๊ถŒํ•œ์„ ์ค„ ๊ฒƒ์ด์ง€๋งŒ, @withoutboats ์˜ ์ œ์•ˆ์ด ๋ถ€๋”ช์ณ ์•ผ ํ•ฉ๋‹ˆ๋‹ค. .

๋‚˜๋Š” default ๊ฐ€ ์ฝ”๋“œ ์ฝ๊ธฐ๋ฅผ ๋‹จ์ˆœํ™”ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์•„๋ฌด๋„ default ์‚ฌ์šฉํ•˜์ง€ ์•Š๋„๋ก ์š”์ฒญํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉ์— ๋Œ€ํ•œ ์—„๊ฒฉํ•œ ๋ฌธ์„œํ™” ๊ทœ์น™์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์—์„œ ๋„์›€์ด๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด ์‹œ์ ์—์„œ std ์˜ default ์— ๋Œ€ํ•ด์„œ๋งŒ ๊ฑฑ์ •ํ•˜๋ฉด๋ฉ๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์‚ฌ๋žŒ๋“ค์ด ๋” ์ž˜ ์ดํ•ดํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ „๋ฌธํ™” RFC ์Šน์ธ์„ ์–ป๋Š” ๋ฐ ๊ธฐ์—ฌํ•œ ์ „๋ฌธํ™” ์‚ฌ์šฉ์— ๋ฌธ์„œ ๊ทœ์น™์ด ๋ถ€๊ณผ ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋–  ์˜ค๋ฆ…๋‹ˆ๋‹ค.

@withoutboats๋Š” "๋ฌด์‹œํ•  ์ˆ˜ ์žˆ์ง€๋งŒ์ด ์ƒ์ž์—์„œ๋งŒ"(์ฆ‰, pub(crate) ์„ ์˜๋ฏธํ•˜๋Š” default ์˜ ์ œํ•œ๋œ ํ˜•์‹์„ ์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— default ํ’€๋ฆผ์— ๋Œ€ํ•œ ๋™๊ธฐ๋ฅผ ์ฝ์„ ๋•Œ ์ •ํ™•ํ•ฉ๋‹ˆ๋‹ค pub(crate) ํ•˜์ง€๋งŒ default )? ๊ทธ๋Ÿฌ๋‚˜ ๋‹จ์ˆœํ•˜๊ฒŒ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด default -ness์˜ ๋ˆˆ๊ธˆ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋Œ€์‹  default ์ƒ๋žต์˜ ์˜๋ฏธ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์„ ์ œ์•ˆํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

์˜ณ์€. default(crate) ์™€ ๊ฐ™์€ ์ผ์„ํ•˜๋Š” ๊ฒƒ์€ ์ง€๋‚˜์นœ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

์„ ํ—˜์ ์œผ๋กœ, ๋‚˜๋Š” ์ƒ์ž๊ฐ€ ์ˆ˜์ถœํ•˜๋Š” ๊ฒƒ์„ ํ†ตํ•ด ๊ทธ๊ฒƒ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. default ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐœ์ธ ๋„์šฐ๋ฏธ ํŠน์„ฑ์„ ๋„์ž…ํ•˜๊ณ  ์ž์‹ ์˜ ์ตœ์ข… impl ์—์„œ ํ˜ธ์ถœ ํ•  ์ˆ˜์—†๋Š” ์ƒํ™ฉ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์‚ฌ์šฉ์ž๊ฐ€ default ์„ ์‚ฌ์šฉํ•˜๊ณ  ์ž์‹ ์˜ ๊ฒƒ์„ ์ œ๊ณตํ•˜์ง€ ์•Š๊ธฐ๋ฅผ ์›ํ•˜์‹ญ๋‹ˆ๊นŒ?

์˜ณ์€. default (crate)์™€ ๊ฐ™์€ ๊ฒƒ์„ํ•˜๋Š” ๊ฒƒ์€ ๊ณผ์ž‰์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

๋™์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ œํ•œ๋œ ํ˜•ํƒœ์˜ ๊ธฐ๋ณธ๊ฐ’์„ ์›ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์ œ์•ˆํ•˜๋ ค๊ณ ํ–ˆ๋‹ค. ๋‚ด ๋™๊ธฐ๋Š” ๋•Œ๋•Œ๋กœ ๊ต์ฐจ๋กœ impls ๋“ฑ์ด ๊ธฐ๋ณธ๊ฐ’์„ ์ถ”๊ฐ€ํ•˜๋„๋ก ๊ฐ•์š”ํ•˜์ง€๋งŒ, ๊ทธ๊ฒƒ์ด ์ž„์˜์˜ ์ƒ์ž๊ฐ€ ๋‹น์‹ ์˜ ํ–‰๋™์„ ๋ฐ”๊พธ๋„๋ก ํ—ˆ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋Š” ์˜๋ฏธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ํšŒ์˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์กฐ๊ธˆ ๋” ์ž์„ธํžˆ ์„ค๋ช…ํ•ด ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

@nikomatsakis ์ €๋„ ๊ฐ™์€ ๋™๊ธฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ œ๊ฐ€ ์ œ์•ˆํ•˜๋Š” ๊ฒƒ์€ ๋” ๋งŽ์€ ๋ ˆ๋ฒ„๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋Œ€์‹  ๋™์ผํ•œ ์ƒ์ž๋ฅผ ์ „๋ฌธํ™”ํ•˜๋Š” ๊ธฐ๋ณธ ์š”๊ตฌ ์‚ฌํ•ญ์„ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. :-)

์šฐ์—ฐํžˆ ๋‚ด ๋ณด๋‚ด์ง€ ์•Š์€์ด ๊ธฐ๋ณธ๊ฐ’์ด ๋” ์ผ๋ฐ˜์ ์ธ ์šฉ๋„ ์ผ ์ˆ˜ ์žˆ๋‹ค๋ฉด #[macro_export] ์™€ ์œ ์‚ฌํ•˜๊ฒŒ #[default_export] ๊ธฐ๋Šฅ์„ ๊ธฐ์–ตํ•˜๊ธฐ๊ฐ€ ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค. ์ค‘๊ฐ„ ์˜ต์…˜์€ pub use ๋˜๋Š” pub mod ํ–‰์— ๋Œ€ํ•ด์ด ๋‚ด๋ณด๋‚ด๊ธฐ ๊ธฐ๋Šฅ์„ ํ—ˆ์šฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์€ Using pub ๋งคํฌ๋กœ 2.0 ์ดํ›„ ๋” ์ข‹์„ ๊ฒƒ์ด๋‹ค ํ‚ค์›Œ๋“œ๊ฐ€ ์ •์ƒ ํ•ญ๋ชฉ์œผ๋กœ ๋งคํฌ๋กœ๋ฅผ ์ง€์›ํ•˜๊ณ  ์‚ฌ์šฉ pub ๋Œ€์‹  #[macro_use] . pub ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ „๋ฐ˜์ ์œผ๋กœ ๊ฐ€์‹œ์„ฑ์„ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ์€ ์ผ๊ด€์„ฑ ์ธก๋ฉด์—์„œ ํฐ ์ด์ ์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@withoutboats ๊ด€๊ณ„์—†์ด, ๋‚˜๋Š” ๋•Œ๋•Œ๋กœ ๋‹น์‹ ์ด ํ˜„์ง€ ์ „๋ฌธํ™”๋ฅผ ์› ํ•˜์ง€๋งŒ ๋ฐ˜๋“œ์‹œ ๋ชจ๋“  ์‚ฌ๋žŒ์—๊ฒŒ ๋ฌธ์„ ์—ด์ง€๋Š” ์•Š์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

pub ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ์ข‹์Šต๋‹ˆ๋‹ค.

pub default fn ๋Š” ๊ธฐ๋Šฅ ์ž์ฒด์˜ ๊ฐ€์‹œ์„ฑ์— ์˜ํ–ฅ์„์ฃผ๋Š” ๊ฒƒ๊ณผ ๋ฐ˜๋Œ€๋กœ "fn์˜ ๊ธฐ๋ณธ๊ฐ’์„ ๊ณต๊ฐœ์ ์œผ๋กœ ๋‚ด๋ณด๋‚ด๋Š” ๊ฒƒ"์„ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์€ ์‹ ๊ทœ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋งค์šฐ ํ˜ผ๋ž€ ์Šค๋Ÿฌ์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@jimmycuadra ๋Š” pub ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๊นŒ? @sgrif ๊ฐ€ ๋” ํ˜ผ๋ž€์Šค๋Ÿฌ์›Œ ๋ณด์ด๋ฉฐ ๋ช…์‹œ ์ ์œผ๋กœ

๋‘˜ ๋‹ค ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ๋ชจํ˜ธํ•˜๊ธฐ ๋•Œ๋ฌธ์— pub default fn ์ •ํ™•ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹จ์ง€ pub ๋ณดํŽธ์ ์œผ๋กœ "๊ทธ ๋ฐ–์˜ ์‚ฌ์ ์ธ ๊ฒƒ์„ ์™ธ๋ถ€์— ๋…ธ์ถœ์‹œํ‚จ๋‹ค"๋Š” ์˜๋ฏธ๋ฅผ ๊ฐ–๋Š” ๊ฐ€์น˜๊ฐ€ ์žˆ๋‹ค๊ณ  ๋งํ•˜๊ณ  ์žˆ์—ˆ๋‹ค. ํ•จ์ˆ˜ ์ž์ฒด๋ฅผ ๊ณต๊ฐœํ•˜๋Š” ๊ฒƒ๊ณผ ํ˜ผ๋™ํ•˜์ง€ ์•Š๋„๋ก ์‹œ๊ฐ์ ์œผ๋กœ ๋‹ค๋ฅธ pub ๋ฅผ ํฌํ•จํ•˜๋Š” ๊ตฌ๋ฌธ์˜ ๊ณต์‹ํ™”๊ฐ€์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•ฝ๊ฐ„์˜ ๊ตฌ๋ฌธ์ด๊ธฐ๋Š”ํ•˜์ง€๋งŒ pub(foo) ์ฒ˜๋Ÿผ ์ž‘๋™ํ•˜๋Š” default(foo) ๋ฐ˜๋Œ€ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๋‘ ๊ฐ€์ง€ ์‚ฌ์ด์˜ ๋Œ€์นญ์ด ๊ตฌ๋ฌธ์˜ ๊ฒฝ์†”ํ•จ๋ณด๋‹ค ์•ฝ๊ฐ„ ๋” ํฝ๋‹ˆ๋‹ค.

Bikeshed ๊ฒฝ๊ณ  : ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์„ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ–ˆ๋‹ค overridable ๋Œ€์‹  default ? ๋ง ๊ทธ๋Œ€๋กœ ๋” ์„ค๋ช…์ ์ด๊ณ  overridable(foo) ๊ฐ€ default(foo) ๋ณด๋‹ค ๋” ์ž˜ ์ฝ์Šต๋‹ˆ๋‹ค. ํ›„์ž๋Š” "์ด๊ฒƒ์€ foo ๋ฒ”์œ„ ๋‚ด์˜ ๊ธฐ๋ณธ๊ฐ’์ด์ง€๋งŒ ๋‹ค๋ฅธ ๊ฒƒ์ด ๊ธฐ๋ณธ๊ฐ’ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ „์ž๋Š” " foo ์˜ ๋ฒ”์œ„ ๋‚ด์—์„œ ์žฌ์ •์˜ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค."๋ผ๊ณ  ๋งํ•˜์ง€๋งŒ ๋งž์Šต๋‹ˆ๋‹ค.

์ฒ˜์Œ ๋‘ ๊ฐ€์ง€ ์งˆ๋ฌธ์€ ์‹ค์ œ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. default ์ˆ˜์ถœํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๋” ์ผ๋ฐ˜์ ์ž…๋‹ˆ๊นŒ? default ness๋ฅผ ๊ธฐ๋ณธ ๋™์ž‘์œผ๋กœ ๋‚ด ๋ณด๋‚ด์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๊นŒ?

์˜ˆ : pub mod mymodule default; ๋ฐ pub use mymodule::MyTrait default; ๋˜๋Š” overridable ์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ๊ณณ์—์„œ ๋‚ด๋ณด๋‚ด๊ธฐ์™€ ์œ ์‚ฌ์„ฑ์„ ์ตœ๋Œ€ํ™” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ๊ฒฝ์šฐ pub use MyModule::MyTrait::{methoda,methodb} default; ์‚ฌ์šฉํ•˜์—ฌ ์ผ๋ถ€ ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•ด์„œ๋งŒ default ness๋ฅผ ๋‚ด๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์–ด๋–ค ๊ฒฝ์šฐ๋„ ์—†์Šต๋‹ˆ๋‹ค : ์–ด์จŒ๋“  Rust์˜ ๋‹ค๋ฅธ ์–ด๋–ค ๊ฒƒ๊ณผ๋„ ์ƒ๋‹นํžˆ ๋‹ค๋ฅธ ๊ณต๊ฐœ์„ฑ์ด ์•„๋‹ˆ๋ผ ์‚ฌ์ƒํ™œ์„ ํ‘œํ˜„ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ default(crate) ์ด ์ด๋Ÿฌํ•œ ๋‚ด๋ณด๋‚ด๊ธฐ๋ฅผ ์ œ์–ดํ•˜๋Š” โ€‹โ€‹์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์ด๋ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ default ness๋ฅผ ๋‚ด๋ณด๋‚ด๊ณ  ๋‚ด ๋ณด๋‚ด์ง€ ์•Š๋Š” ๊ฒƒ์ด ๋น„๊ต์  ์ผ๋ฐ˜์ ์ด๋ผ๋ฉด, ์•„๋งˆ๋„ ์˜ˆ ๋˜๋Š” ์•„๋‹ˆ์˜ค ์ค‘ ํ•˜๋‚˜๋ฅผ ์ž„์˜๋กœ ์„ ํƒํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋‹ค์‹œ pub use MyModule::MyTrait::{methoda,methodb} default; ์ข‹์Šต๋‹ˆ๋‹ค.

์ด ๋ชจ๋“  ํ‘œ๊ธฐ๋ฒ•์€ ์–ด์จŒ๋“  ํ˜ธํ™˜๋ฉ๋‹ˆ๋‹ค. ๋˜ ๋‹ค๋ฅธ ์˜ต์…˜์€ default s๋ฅผ ๋‹ซ๋Š” ํŠน๋ณ„ํ•œ impl ์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ๋ณต์žกํ•˜๊ณ  ์ด์ƒํ•˜๊ฒŒ ๋“ค๋ฆฝ๋‹ˆ๋‹ค.

@burdges ๊ฑฐ๊พธ๋กœ "์˜ˆ"์™€ "์•„๋‹ˆ์˜ค"๋ผ๋Š” ๋ ˆ์ด๋ธ”์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ๋‹น์‹ ์ด ๋งํ•˜๋Š” ๊ฒƒ์„ ์˜คํ•ดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

๋„ค, ์ด๋Ÿฐ! ๊ฒฐ์ •๋œ!

impl<T> Borrow<T> for T where T: ?Sized ์žˆ์œผ๋ฏ€๋กœ Borrow<T> ๋ฐ”์šด๋“œ๋Š” ์†Œ์œ  ๋œ ๊ฐ’์„ ์ฐจ์šฉ ๋œ ๊ฒƒ์ฒ˜๋Ÿผ ์ฒ˜๋ฆฌ ํ•  ์ˆ˜ โ€‹โ€‹์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ํ˜ธ์ถœ ๋ฉ€๋ฆฌ ์ตœ์ ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์ „๋ฌธํ™”๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„์žˆ์„ ๊ฒƒ ๊ฐ™๊ตฐ์š” clone ์—์„œ Borrow<T> , ๊ทธ๋ž˜?

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 ํ•˜๋‚˜๊ฐ€ ์•„๋งˆ๋„์ด ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ตฌ์† Sized ๋ฐ˜ํ™˜ ํ•  ๋•Œ T .

๋˜ ๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์€

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://botbot.me/mozilla/rust-lang/

๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ๋„๋‹ฌ ํ•œ ๋ชจ๋“  ๊ฒฐ๋ก ์— ๋Œ€ํ•ด 100 % ํ™•์‹ ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ ์‚ฌ์‹ค ์ดํ›„์— Niko์˜ ์˜๊ฒฌ์ด ๊ณ ์–‘ ๋œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ž ์‹œ ๋™์•ˆ ๊ทธ๊ฒƒ์€ ๋‚˜์—๊ฒŒ ์•ฝ๊ฐ„ ๋ฌต์‹œ์ ์ธ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์˜€์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์ƒ๋‹นํžˆ ํ™•์‹ ํ•˜๋Š” ํ•œ ๊ฐ€์ง€๋Š” default ๋ฅผ ์š”๊ตฌํ•˜๋Š” ๊ฒƒ์€ ์ƒˆ๋กœ์šด default impls๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ํ•ญ์ƒ ์—ญ ํ˜ธํ™˜๋œ๋‹ค๋Š” ๋ณด์žฅ๊ณผ ํ˜ธํ™˜ ๋  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๋ฐ๋ชจ์ž…๋‹ˆ๋‹ค.

์ƒ์ž 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 impl์ด C for T where T: B ์˜ ํŠน์ˆ˜ํ™” ๋ถˆ๊ฐ€๋Šฅํ•œ ๋ธ”๋žญํ‚ท impl๊ณผ ์ถฉ๋Œํ•ฉ๋‹ˆ๋‹ค.

์ƒ์ž parent v 1.1.0

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

์ด impl์ด ์ถ”๊ฐ€๋˜์—ˆ์œผ๋ฉฐ ์™„์ „ํžˆ ํŠน์ˆ˜ํ™” ํ•  ์ˆ˜์žˆ๋Š” impl์ด๋ฏ€๋กœ ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์ด ๊นจ์ง€์ง€ ์•Š๋Š” ๋ณ€๊ฒฝ์ด๋ผ๊ณ  ๋งํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ์ „ ์ด์  ํ•จ์ถ•์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. "all A impl B (ํŠน์ˆ˜ํ™” ๊ฐ€๋Šฅ)"๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ด๋ฏธ "all B impl C (ํŠน์ˆ˜ํ™” ๋ถˆ๊ฐ€๋Šฅ)"๋ฅผ ๊ฐ€์กŒ๊ณ  "all A impl C (ํŠน์ˆ˜ํ™” ๋ถˆ๊ฐ€๋Šฅ)"๋ผ๋Š” ๋ฌธ๊ตฌ๋ฅผ ์•”์‹œ ์ ์œผ๋กœ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ". ์ด์ œ ์ž์‹ ์ƒ์ž๋ฅผ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.


ํŠน์ˆ˜ํ™” ๊ฐ€๋Šฅํ•œ impl์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ๋ธŒ๋ ˆ์ดํ‚น ์ฒด์ธ์ง€๊ฐ€ ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•œ๋‹ค๋Š” ์•„์ด๋””์–ด๊ฐ€ ์™„์ „ํžˆ ์ฐฝ ๋ฐ–์—์žˆ๋Š” ๊ฒฝ์šฐ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Aaron์ด (์œ„์— ๋งํฌ ๋œ ๋กœ๊ทธ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด) ๊ธฐ๋ณธ๊ฐ’๊ณผ ๊ด€๋ จํ•˜์—ฌ ๋™๋“ฑํ•œ ๋ณด์žฅ์„ํ•˜๋Š” impls๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Œ์„ ๋ณด์—ฌ ์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. . ๊ทธ๋Ÿฌ๋‚˜ Niko์˜ ์ดํ›„ ์˜๊ฒฌ์€ ์ด๋Ÿฌํ•œ impls๊ฐ€ ๊ณ ์•„ ๊ทœ์น™์— ์˜ํ•ด ๊ธˆ์ง€ ๋  ์ˆ˜ ์žˆ์Œ์„ ์‹œ์‚ฌํ•ฉ๋‹ˆ๋‹ค (๋˜๋Š” ์ตœ์†Œํ•œ ๊ธˆ์ง€ ๊ฐ€๋Šฅ).

๋”ฐ๋ผ์„œ 'impls is non-breaking'๋ณด์ฆ์€ ๊ตฌ์ œ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๊ฐ€ ๋ถˆํ™•์‹คํ•˜์ง€๋งŒ ๋‹จ์ˆœ ์ตœ์ข…์„ฑ์— ๋Œ€ํ•œ ๋ช…์‹œ์ ์ธ ์ œ์–ด์™€ ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” ๊ฒƒ์€ ํ™•์‹คํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์„ ํ—ˆ์šฉ ํ•  ๊ณ„ํš์ด ์žˆ์Šต๋‹ˆ๊นŒ?

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 ์— ๋ฐ”์ธ๋”ฉ ๋œ ํ˜•์‹ ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€์žˆ๋Š” ํ…œํ”Œ๋ฆฟ ํ•จ์ˆ˜์— ๋Œ€ํ•œ ํŠน์ˆ˜ํ™”์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ํŠน์ˆ˜ ๋ฒ„์ „์€ B ์— ๋ฐ”์ธ๋”ฉ๋ฉ๋‹ˆ๋‹ค ( A ).

@torkleyy ๋Š” ํ˜„์žฌ๋Š” ์•„๋‹ˆ์ง€๋งŒ T: Read ๋ฐ T: BufRead ์— ๋Œ€ํ•ด ๊ตฌํ˜„๋˜๊ณ  ํ•ด๋‹น ํŠน์„ฑ์˜ impls์— ํŠนํ™”ํ•˜๋ ค๋Š” ์ฝ”๋“œ ๋ถ€๋ถ„์„ ํฌํ•จํ•˜๋Š” ํŠน์„ฑ์„ ๋งŒ๋“ค์–ด ๋น„๋ฐ€๋ฆฌ์— ์ˆ˜ํ–‰ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณต๊ฐœ API์—์„œ ๋ณผ ํ•„์š”๋„ ์—†์Šต๋‹ˆ๋‹ค.

์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ์— ๊ด€ํ•ด์„œ๋Š” ๊ณ ์•„ ๊ทœ์น™ ๋•๋ถ„์— ๋‹ค์Œ ๊ทœ์น™์—์„œ ๋ฒ—์–ด๋‚  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

_impl์€ ๋‹ค์Œ์„ ์ œ์™ธ ํ•˜๊ณ ๋Š” ํ•˜์œ„ ํ˜ธํ™˜์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

  • _ ๊ฐ„์ฒด๋˜๋Š” ํŠน์„ฑ์€ ์ž๋™ ํŠน์„ฑ์ž…๋‹ˆ๋‹ค ._
  • _ ์ˆ˜์‹ ์ž๋Š” ์œ ํ˜• ๋งค๊ฐœ ๋ณ€์ˆ˜์ด๋ฉฐ impl์˜ ๋ชจ๋“  ํŠน์„ฑ์€ ์ด์ „์— ์กด์žฌํ–ˆ์Šต๋‹ˆ๋‹ค ._

์ฆ‰, ๋ฌธ์ œ๊ฐ€๋˜๋Š” ๋ชจ๋“  ์˜ˆ์ œ์—์„œ ์ถ”๊ฐ€ ๋œ impl์ด ๋ธ”๋žญํ‚ท impl์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์™„์ „ ๊ธฐ๋ณธ ๋ธ”๋žญํ‚ท impls๋„ ๊ดœ์ฐฎ๋‹ค๊ณ  ๋งํ•˜๊ณ  ์‹ถ์—ˆ์ง€๋งŒ, ๊ธฐ์กด ๋ธ”๋žญํ‚ท impls๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ํฐ ๋ณ€ํ™”๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋งํ•ด์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” ๊ทธ ์•ž์—์„œ ์šฐ๋ฆฌ๊ฐ€ ์–ด๋–ค ๋ณด์žฅ์„ํ•˜๊ณ  ์‹ถ์€๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํฌ๋ ˆ์ดํŠธ๋ฅผ ํ™•์ธํ•˜๊ณ  ๋ฉ”์ด์ € ๋ฒ„์ „์„ ๋Š˜๋ฆด ํ•„์š”๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”.

์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ์— ๊ด€ํ•ด์„œ๋Š” ๊ณ ์•„ ๊ทœ์น™ ๋•๋ถ„์— ๋‹ค์Œ ๊ทœ์น™์—์„œ ๋ฒ—์–ด๋‚  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

_impl์€ ๋‹ค์Œ์„ ์ œ์™ธ ํ•˜๊ณ ๋Š” ํ•˜์œ„ ํ˜ธํ™˜์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

  • _ ๊ฐ„์ฒด๋˜๋Š” ํŠน์„ฑ์€ ์ž๋™ ํŠน์„ฑ์ž…๋‹ˆ๋‹ค ._
  • _ ์ˆ˜์‹ ์ž๋Š” ์œ ํ˜• ๋งค๊ฐœ ๋ณ€์ˆ˜์ด๋ฉฐ impl์˜ ๋ชจ๋“  ํŠน์„ฑ์€ ์ด์ „์— ์กด์žฌํ–ˆ์Šต๋‹ˆ๋‹ค ._

์ฆ‰, ๋ฌธ์ œ๊ฐ€๋˜๋Š” ๋ชจ๋“  ์˜ˆ์ œ์—์„œ ์ถ”๊ฐ€ ๋œ impl์ด ๋ธ”๋žญํ‚ท impl์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์™„์ „ ๊ธฐ๋ณธ ๋ธ”๋žญํ‚ท impls๋„ ๊ดœ์ฐฎ๋‹ค๊ณ  ๋งํ•˜๊ณ  ์‹ถ์—ˆ์ง€๋งŒ, ๊ธฐ์กด ๋ธ”๋žญํ‚ท impls๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ํฐ ๋ณ€ํ™”๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋งํ•ด์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ผ์ฃผ์ผ ํ›„ ๋งŽ์€ ๋…ผ์˜๊ฐ€ ์žˆ์—ˆ์ง€๋งŒ ๋ถˆํ–‰ํžˆ๋„ ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒƒ์œผ๋กœ ํŒ๋ช…๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ์–ป์€ ๊ฒฐ๊ณผ๋Š” : crying_cat_face :์ด์ง€๋งŒ ์ œ๊ฐ€ ๊ฑฐ๊ธฐ์— ์“ด ๋‚ด์šฉ์€ ๋‹น์‹ ์˜ ๊ฒฐ๋ก ๊ณผ ๋™์ผํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋ธ”๋žญํ‚ท impls๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–ค ์ผ์ด ์žˆ์–ด๋„ ๋ธŒ๋ ˆ์ดํ‚น ์ฒด์ธ์ง€์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‹ด์š” impls (๋ฐ auto trait impls) ๋‚ด๊ฐ€ ์•„๋Š” ํ•œ, non-blanket 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, ๋‚˜๋Š” ์–ด๋–ค ๋ณด์ธ๋‹ค ๋‹น์‹ ์ด ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๊ณ , ๋‚˜๋ณด๋‹ค๋Š” ๋‹น์‹ ์˜ ๋‘ ๊ธ€ ๋จธ๋ฆฌ ๊ธฐํ˜ธ ๋ชฉ๋ก์„ ์ดํ•ด?

@aturon ์˜ˆ, ๋‚˜๋Š” '๋˜๋Š”'์„ ์˜๋ฏธํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ๋ธŒ๋ ˆ์ดํ‚น ์ฒด์ธ์ง€ ์ธ ๋‘ ๊ฐ€์ง€ ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. ์ž๋™ ํŠน์„ฑ impl์€ ์•„๋ฌด๋ฆฌ ๊ตฌ์ฒด์  ์ด๊ฑด๊ฐ„์— ๋ถ€์ •์ ์ธ ์ถ”๋ก ์„ ํ—ˆ์šฉํ•˜๋Š” ๋ฐฉ์‹ ๋•Œ๋ฌธ์— ํฐ ๋ณ€ํ™”์ž…๋‹ˆ๋‹ค : https://is.gd/k4Xtlp

์ฆ‰, ์ƒˆ ์ด๋ฆ„์„ ํฌํ•จํ•˜์ง€ ์•Š๋Š” ํ•œ. AFAIK ์ƒˆ ์ด๋ฆ„์„ ํฌํ•จํ•˜๋Š” impl์€ ์ ˆ๋Œ€ ๊นจ์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@withoutboats ์ž๋™ ํŠน์„ฑ์— ๋Œ€ํ•œ ๋ถ€์ •์ ์ธ ๋…ผ๋ฆฌ์— ์˜์กดํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ์ œํ•œ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ / ์ œํ•œ Send ์ถ”๊ฐ€ํ•˜๋Š” ์—…์ŠคํŠธ๋ฆผ ํฌ๋ ˆ์ดํŠธ์— ์˜ํ•ด ๊นจ์งˆ ์ˆ˜์žˆ๋Š” impls์— ๋Œ€ํ•ด ๊ฒฝ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ ๊ฐ€์žฅ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

  1. ์•ˆ์ •์ ์ธ ์ „๋ฌธํ™”, ์ „๋žต์  ์žฅ์†Œ์— default ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๊ฒฝ๊ณ ๋ฅผ ๊ทน๋ณต ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ).
  2. Rc ์™€ ๊ฐ™์€ ์œ ํ˜•์€ ์ ˆ๋Œ€ Send ๊ฐ€ ๋˜์ง€ ์•Š์„ ์˜๋„๋ฅผ ์„ ์–ธ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ช…์‹œ ์  ๋ถ€์ • impls์˜ ์ผ๋ถ€ ํ˜•์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.ํ•˜์ง€๋งŒ ์ž๋™ ํŠน์„ฑ์— ๋Œ€ํ•œ ๊ฒƒ์ด ์žˆ์œผ๋ฏ€๋กœ์ด๋ฅผ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ•ํ•œ ๋™๊ธฐ๊ฐ€ ์žˆ๋Š”์ง€ ์•„๋‹Œ์ง€์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋Š” ๊ฒƒ ๊ฐ™์•„์š”. ์ด๋ฏธ ๋ฆด๋ฆฌ์Šค ํ•œ ํ›„์— ์œ ํ˜•์ด unsafe impl Send/Sync ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์„ ๊นจ๋‹ซ์ง€ ๋ชปํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์•ˆ์ „ ํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ๊ทธ๊ฒƒ์ด ์•ˆ์ „ ํ•  ๊ฒƒ์ด๋ผ๋Š” ์˜ˆ์ง€๊ฐ€์žˆ๋Š” ์œ ํ˜•์„ ์ž‘์„ฑํ–ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค (์œ ํ˜•์˜ ์š”์ ์ด๊ธฐ ๋•Œ๋ฌธ์—).

๋‚˜๋Š” ํ•ญ์ƒ ์‚ฌ์‹ค ๋’ค์— unsafe impl Send/Sync ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๋•Œ๋กœ๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋งŒ๋“ค์—ˆ ๊ธฐ ๋•Œ๋ฌธ์—, ๋•Œ๋กœ๋Š” ๋‚ด๊ฐ€ ์ธํ„ฐํŽ˜์ด์Šคํ•˜๊ณ ์žˆ๋Š” C API๊ฐ€ ์Šค๋ ˆ๋“œ๊ฐ„์— ๊ณต์œ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜ ๊ธฐ ๋•Œ๋ฌธ์—, ๋•Œ๋กœ๋Š” ๋ฌด์–ธ๊ฐ€๊ฐ€ Send / Sync ์ด์–ด์•ผํ•˜๋Š”์ง€ ์—ฌ๋ถ€๊ฐ€ ์ œ๊ฐ€ ์œ ํ˜•์„ ์†Œ๊ฐœ ํ•  ๋•Œ ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค.

C API๋ฅผ ๋ฐ”์ธ๋”ฉ ํ•  ๋•Œ๋„ ์‚ฌ์‹ค ๋’ค์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ข…์ข… ๋ˆ„๊ตฐ๊ฐ€ ๋ช…์‹œ ์ ์œผ๋กœ ํ•ด๋‹น ๊ฒฝ๊ณ„๋ฅผ ์š”์ฒญํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋ณด์žฅํ•˜๋Š” ๋‚ด์šฉ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

์ง€๊ธˆ ๋‹น์žฅ ๊ด€๋ จ ํŠน์„ฑ์„ ์ „๋ฌธํ™”ํ•˜๋Š” ๋ฐฉ์‹์— ๋Œ€ํ•ด ์ œ๊ฐ€ ์ข‹์•„ํ•˜์ง€ ์•Š๋Š” ์ ์€์ด ํŒจํ„ด์ด ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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 in traits๋Š” ์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ํŒจํ„ด์— ๋Œ€ํ•œ ๋งŽ์€ ์š•๊ตฌ๋ฅผ ํ’€์–ด ์ฃผ์ง€๋งŒ, generic impl์ด ์œ ํšจํ•˜์ง€๋งŒ ์œ ํ˜• ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ์ „๋ฌธํ™”๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๋” ๋‚˜์€ ์†”๋ฃจ์…˜์ด ์—†๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. ?

@withoutboats ์˜ˆ, ์ด๊ฒƒ์€ ๋””์ž์ธ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ๋˜์ง€ ์•Š์€ ์ฃผ์š” ์งˆ๋ฌธ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค (์ตœ๊ทผ ํ† ๋ก ์—์„œ ์–ธ๊ธ‰ํ•˜๋Š” ๊ฒƒ์„ ์žŠ์—ˆ์Šต๋‹ˆ๋‹ค). ์›๋ž˜ RFC ์Šค๋ ˆ๋“œ์—์„œ ์ด์— ๋Œ€ํ•œ ์ƒ๋‹นํ•œ ๋…ผ์˜๊ฐ€ ์žˆ์ง€๋งŒ ๊ณง ์˜ต์…˜ / ์ƒ์‡„์— ๋Œ€ํ•œ ์š”์•ฝ์„ ์ž‘์„ฑํ•˜๋ ค๊ณ ํ•ฉ๋‹ˆ๋‹ค.

@aturon ํ˜„์žฌ ์†”๋ฃจ์…˜์ด ๊ฐ€์žฅ ๋ณด์ˆ˜์ ์ž…๋‹ˆ๊นŒ (์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๋ชจ๋“  ๊ฒƒ๊ณผ ํ˜ธํ™˜ ๊ฐ€๋Šฅ) ์•„๋‹ˆ๋ฉด ์•ˆ์ •ํ™”ํ•˜๊ธฐ ์ „์— ๊ฒฐ์ •ํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ?

๊ฐœ์ธ์ ์œผ๋กœ @withoutboats๊ฐ€ ์ œ๊ธฐ ํ•œ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ์œ ์ผํ•œ ํ•ด๊ฒฐ์ฑ…์€ default ํƒœ๊ทธ๋ฅผ ์ง€์ •ํ•  ๋•Œ ํ•ญ๋ชฉ์„ "๊ทธ๋ฃนํ™”"ํ•  ์ˆ˜ ์žˆ๋„๋กํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ์ผ์ข…์˜ ๋” ๋‚ซ๊ณ  ๋” ๋‚˜์€ ํ•ด๊ฒฐ์ฑ…์ด์ง€๋งŒ, ๋” ๋‚˜์ ์ˆ˜๋ก ๋” ์ข‹์€ ๋ณ€์ข… (๋ชจ๋“  ์ˆ˜๋‹จ์„ ์žฌ์ •์˜ํ•˜๋Š” ๊ฒƒ)์ด ํ›จ์”ฌ ๋” ๋‚˜์˜๋‹ค๊ณ  ๋Š๋‚๋‹ˆ๋‹ค. (ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ @withoutboats ์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ ๋ฐฉ์‹์€ ํ˜ผ๋ž€ ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. impl BufRead ์˜ ๋ฐ˜ํ™˜ ์œ ํ˜•์œผ๋กœ Buffer ์„ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  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์˜ ๋ฐ˜ํ™˜ ์œ ํ˜•์œผ๋กœ impl BufRead๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  Self :: BufReader๋ฅผ ์˜๋ฏธํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ, ์†”๋ฃจ์…˜์„ impl Trait ๊ธฐ๋ฐ˜์œผ๋กœ ์ˆ˜์ • ํ•œ ๋‹ค์Œ ๋‹ค์‹œ ์ „ํ™˜ํ–ˆ์ง€๋งŒ ํŠน์„ฑ์˜ ๋ฐ˜ํ™˜ ์œ ํ˜•์„ ๋†“์ณค์Šต๋‹ˆ๋‹ค.

์–ด์ฉŒ๋ฉด์˜ ํƒ€์ž… ์‹œ์Šคํ…œ๊ณผ ๊ฐ™์€ ์ด ๊ฐ€ ๋…น์Šฌ๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ๋ณด์ด์ง€๋งŒ, ๋ช‡ ๊ฐ€์ง€ ๊ธฐ๋Šฅ, ์ฆ‰ ํ˜„์žฌ์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์–ธ์–ด๋„ ์žฌ๋ฏธ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
( 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 ๊ฐ€ ํŠน๋ณ„ํ•˜๊ธฐ ๋•Œ๋ฌธ ์ผ๊นŒ์š” , ์•„๋‹ˆ๋ฉด Display ๊ฐ€ Default ๊ฐ€ ํŠœํ”Œ์— ๋Œ€ํ•ด ๊ตฌํ˜„๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ผ๊นŒ์š”?

๋ฟก๋ฟก
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
    }
}

๊ธฐ๋ณธ์ ์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ๋‹จ์œ„ ์ธ ๊ฒฝ์šฐ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
์ถฉ๋Œํ•˜๋Š” ๊ตฌํ˜„์— ๋Œ€ํ•ด ๋™์ผํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
์ „๋ฌธํ™”๋กœ ๊ทธ๋ ‡๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ (๋˜๋Š” ๊ฐ€๋Šฅํ• ๊นŒ์š”)?
๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด ๋Œ€์•ˆ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

ํŽธ์ง‘ : ์ปดํŒŒ์ผ๋˜์ง€ ์•Š๋Š” ์ด์œ ๋ฅผ ์•Œ์•„ ๋‚ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
T ์—์„œ for T ๋ณด๋‹ค ์ผ๋ฐ˜์ ์ด๋‹ค () ์—์„œ for () ์ œ ์žˆ๋„๋ก impl ํŠน์„ฑํ™” ๋  ์ˆ˜ ์—†๋‹ค.
๊ทธ๋ฆฌ๊ณ  C ๋Š” C: Fn(Self) -> R ๋ณด๋‹ค ์ผ๋ฐ˜์ ์ด๋ฏ€๋กœ ๋‘ ๋ฒˆ์งธ impl ๋Š” ์ „๋ฌธํ™” ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
๋‚ด๊ฐ€ ํ‹€๋ ธ๋‹ค๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”.
๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ์—ฌ์ „ํžˆ Display ์˜ ์ฒซ ๋ฒˆ์งธ ์˜ˆ์ œ์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋ฅผ ์•Œ์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ํ˜„์žฌ ์˜ฌ๋ฐ”๋ฅธ ๋™์ž‘์ž…๋‹ˆ๋‹ค.

Custom ์˜ˆ์ œ์—์„œ ์ด๋Ÿฌํ•œ impls๋Š” ํŠน๋ณ„ํ•œ ๋กœ์ปฌ ๋ถ€์ •์  ์ถ”๋ก ์œผ๋กœ ์ธํ•ด ๊ฒน์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ˜•์งˆ์ด ์ƒ์ž์—์„œ์ด๊ธฐ ๋•Œ๋ฌธ์—, ์šฐ๋ฆฌ๋Š” ์ถ”๋ก  ํ•  ์ˆ˜ () ์˜ IMPLํ•˜์ง€ ์•Š๋Š”, Custom ,ํ•˜์ง€ ์ค‘๋ณต ์•Š์Šต๋‹ˆ๋‹ค T: Custom . ์ „๋ฌธํ™”๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๋Š” ๋‹น์‹ ์˜ ์ƒ์ž์— ์žˆ์ง€ ์•Š์€ ํŠน์„ฑ์— ๋Œ€ํ•ด ์ด๋Ÿฌํ•œ ๋ถ€์ •์ ์ธ ์ถ”๋ก ์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๋‹ค์Œ ๋ฆด๋ฆฌ์Šค์—์„œ Display for () ๋ฅผ ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด๊ฒƒ์ด ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด๋˜๋Š” ๊ฒƒ์„ ์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋„์„œ๊ด€์ด ์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ๋ณ€ํ™”๋ฅผ ์ž์œ ๋กญ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ()๊ฐ€ ๋””์Šคํ”Œ๋ ˆ์ด๋ฅผ ๋‹จ์ˆœํ™”ํ•˜์ง€ ์•Š๋”๋ผ๋„ ์˜ค๋ฒ„๋žฉ ๊ฒ€์‚ฌ์—์„œ ํ•ด๋‹น ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ()๋Š” Display๋ฅผ ์˜๋ฏธํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— T: Display ๋ณด๋‹ค ๊ตฌ์ฒด์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์ „๋ฌธํ™”๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๋ฐ˜๋ฉด, Default์˜ ๊ฒฝ์šฐ (): Default ์ด๋ฏ€๋กœ ํ•ด๋‹น impl์ด T: Default ๋ณด๋‹ค ๋” ๊ตฌ์ฒด์ ์ž…๋‹ˆ๋‹ค.

์ด์™€ ๊ฐ™์€ Impls๋Š” ๊ฒน์น˜๊ฑฐ๋‚˜ ๊ฒน์น˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ๊ฐ€์ • ํ•  ์ˆ˜์—†๋Š” ์ผ์ข…์˜ '๋ฆผ๋ณด'์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š”์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์›์น™์ ์ธ ๋ฐฉ๋ฒ•์„ ์ฐพ์œผ๋ ค๊ณ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ์ „๋ฌธํ™”์˜ ์ฒซ ๋ฒˆ์งธ ๊ตฌํ˜„์ด ์•„๋‹ˆ๋ฉฐ ๋‚˜์ค‘์— ํ•ด๋‹น ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ํ•˜์œ„ ํ˜ธํ™˜์„ฑ ํ™•์žฅ์ž…๋‹ˆ๋‹ค.

ํ‰์ƒ ๊ด€๋ จ ๊ฑด์ „์„ฑ ๋ฌธ์ œ๋ฅผ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•ด # 40582๋ฅผ ์ œ์ถœํ–ˆ์Šต๋‹ˆ๋‹ค.

์ „๋ฌธํ™”๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ๋ฌธ์ œ๊ฐ€์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. @antoyo ๊ฐ€ ๊ฐ€์ง€๊ณ ์žˆ๋Š” ๊ฒƒ๊ณผ ์™„์ „ํžˆ ๊ฐ™์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋ณ„๋„์˜ ๋ฌธ์ œ # 41140์œผ๋กœ ์ œ์ถœํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์—ฌ๊ธฐ์— ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@ afonso360 ์•„๋‹ˆ์š”, ๋ณ„๋„์˜ ๋ฌธ์ œ๋Š” ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์ธ ์š”์  :์ด ์‹œ์  ์—์„œ Chalk ์ž‘์—…์—์„œ ์ „๋ฌธํ™”์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ž‘์—…์ด ์ฐจ๋‹จ๋˜์–ด ๊ฑด์ „์„ฑ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๊ณ  ์˜ค๋Š˜๋‚  ํƒ€๊ฒฉ์„ ์ž…์€ ICE๋ฅผ ํ•ด๊ฒฐํ•  ๊ฐ€๋Šฅ์„ฑ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€ ์ด๊ฒƒ์ด ๋ฒ„๊ทธ์ธ์ง€ ๋˜๋Š” ์˜๋„์ ์œผ๋กœ ๊ธˆ์ง€ ๋œ ๊ฒƒ์ธ์ง€ ๋ช…ํ™•ํžˆ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? https://is.gd/pBvefi

@sgrif ์—ฌ๊ธฐ์„œ ๋ฌธ์ œ๋Š” ๊ธฐ๋ณธ ๊ด€๋ จ ์œ ํ˜•์˜ ํˆฌ์˜์ด ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ง„๋‹จ์ด ๋” ๋‚˜์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค : https://github.com/rust-lang/rust/issues/33481

ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š” ์ด์œ ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์„ค๋ช…ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ณ ์•„ ๊ทœ์น™์„ ์œ„๋ฐ˜ํ•˜๋ฏ€๋กœ ๋” ์ด์ƒ ํŠน์ • impl์„ ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ์ฃผ์„์€ ๊ฑด ์ „ํ•จ์„ ์š”๊ตฌํ•˜๊ธฐ ์œ„ํ•ด ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” (์ด์œ ๋Š” ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ) ํ•„์š”ํ•˜๊ณ  ๋‹ค๋ฅธ ๊ฒฝ์šฐ์—๋Š” ์ธํ„ฐํŽ˜์ด์Šค ์†Œ๋น„์ž๊ฐ€ ์ถ”์ƒ ์œ ํ˜•์œผ๋กœ ์ทจ๊ธ‰ํ•˜๋„๋ก ๊ฐ•์ œํ•ด์•ผ ํ•จ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค : https://github.com/rust- lang / rust / blob / e5e664f / src / librustc / traits / project.rs # L41

๋ˆ„๊ตฌ๋“ ์ง€ https://github.com/rust-lang/rust/issues/31844#issuecomment -266221638์„ ๋ณผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๊นŒ? ๊ทธ impls๋Š” ๋‚ด๊ฐ€ ๋งํ•  ์ˆ˜์žˆ๋Š” ํ•œ ์ „๋ฌธํ™”์™€ ํ•จ๊ป˜ ์œ ํšจํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๋“ค์„ ๋ง‰๋Š” ๋ฒ„๊ทธ๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@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 ๋ณด๋‹ค ๋” ๊ตฌ์ฒด์  Option<R> ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ–ˆ์ง€๋งŒ ๋ฌผ๋ก  ์•ž์œผ๋กœ impl<R> Into<R> for Option<R> ๋ฅผ ๋ง‰๋Š” ๊ฒƒ์€ ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์ด ์™œ ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์•ž์œผ๋กœ impl<R> Into<R> for Option<R> ๊ฐ€ ์ถ”๊ฐ€ ๋˜๋”๋ผ๋„ Rust๊ฐ€ default ๊ฐ€ ์•„๋‹Œ ๊ตฌํ˜„์„ ์„ ํƒํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ œ๊ฐ€ ๋ณผ ์ˆ˜์žˆ๋Š” ํ•œ์ด ์ฝ”๋“œ๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์€ forward- ์ ํ•ฉ์„ฑ.

์ „๋ฐ˜์ ์œผ๋กœ ์ €๋Š” ์ „๋ฌธํ™”๊ฐ€ ํ•จ๊ป˜ ์ž‘์—…ํ•˜๋Š” ๋ฐ ๋งค์šฐ ์‹ค๋ง ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์ผํ•˜๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•˜๋Š” ๊ฑฐ์˜ ๋ชจ๋“  ๊ฒƒ์ด ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ „๋ฌธํ™”๋กœ ์„ฑ๊ณตํ•œ ์œ ์ผํ•œ ๊ฒฝ์šฐ๋Š” T where T: A ๋ฐ T where T: A + B ๋ฅผ ํฌํ•จํ•˜๋Š” ๋‘ ๊ฐœ์˜ 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 ์œ„์˜ ์˜ˆ์—์„œ ๊ด€๋ จ ์œ ํ˜• ๋งŒ ์ „๋ฌธํ™” ํ•œ ๊ฒฝ์šฐ defaulti impl ์˜ generate ๋Š” typecheckํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

์—ฌ๊ธฐ ์Šค๋ ˆ๋“œ์— ๋งํฌ

@ 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 ํŒŒ์ƒ์€ ์œ„ํ—˜ํ•˜๋ฉฐ ๋งค์šฐ ๋ฏธ๋ฌ˜ํ•œ ๋ฒ„๊ทธ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ์ด๋Ÿฌํ•œ ๊ธฐ๋ณธ impls๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋Ÿฌํ•œ ํŠน์„ฑ์„ ํŒŒ์ƒํ•˜๋ ค๋Š” ์œ ํ˜น์ด ๋œํ•˜๋ฏ€๋กœ ๋ฌธ์ œ๊ฐ€ ๋‹ค์†Œ ์™„ํ™”๋ฉ๋‹ˆ๋‹ค.


๋˜๋Š” ์ „๋ฌธํ™”๋ฅผ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด ํŒŒ์ƒ์„ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด #[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 ์ฐธ์กฐ

๊ฒฐ๊ตญ, I'ld ์‚ฌ๋ž‘ ๋‚ด๊ฐ€ ์—ฌ๊ธฐ @nikomatsakis์— ์˜ํ•ด ์ œ์•ˆ ๋œ ๊ตฌ๋ฌธ ์ „๋ฌธ ๊ทธ๋ฃน์„ ํ˜ธ์ถœํ•˜๊ณ ์žˆ๋Š” ๋ฌด์Šจ์„ ๋ณผ ์ˆ˜ https://github.com/rust-lang/rust/issues/31844#issuecomment ๋‚ด๊ฒŒ๋กœ -249355377 ๋…๋ฆฝ์ . ๋‚˜์ค‘์— ์ „๋ฌธํ™” ์•ˆ์ •ํ™”์— ๊ฐ€๊นŒ์›Œ์ง€๋ฉด ํ•ด๋‹น ์ œ์•ˆ์— ๋Œ€ํ•œ RFC๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์•„๋ฌด๋„ ๋ณด์ง€ ๋ชปํ•œ ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ ํ•˜์—ฌ์ด ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ ์€ ํ‰์ƒ ๊ธฐ๋ฐ˜ ํŒŒ๊ฒฌ์— ์ง๋ฉดํ•˜์—ฌ ์ „๋ฌธํ™”๋ฅผ์œ„ํ•œ ์ œ์•ˆ์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

๋ฒ ํƒ€์—์„œ ์นดํ”ผ ํด๋กœ์ € ๊ฐ€ ์ด๋ฏธ ์•ˆ์ •ํ™” ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ์ž๋Š” ์ด์ œ ์ „๋ฌธํ™”์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ๋™๊ธฐ๋ฅผ ๊ฐ–๊ฒŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ด์œ ๋Š” Fn ๋ฐ FnOnce + Clone ๋Š” ๋‘ ๊ฐœ์˜ ๊ฒน์น˜๋Š” ํด๋กœ์ € ์„ธํŠธ๋ฅผ ๋‚˜ํƒ€๋‚ด๋ฉฐ, ๋งŽ์€ ๊ฒฝ์šฐ ๋‘˜ ๋‹ค์— ๋Œ€ํ•œ ํŠน์„ฑ์„ ๊ตฌํ˜„ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

rfc 2132 ์˜ ๋ฌธ๊ตฌ๊ฐ€ 5 ๊ฐ€์ง€ ์œ ํ˜•์˜ ํด๋กœ์ € ๋งŒ ์žˆ์Œ์„ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • FnOnce (์บก์ฒ˜ ๋œ ๋ชจ๋“  ๋ณ€์ˆ˜๊ฐ€ Copy ๋˜๋Š” Clone ์ด ์•„๋‹Œ Copy move ํด๋กœ์ €)
  • FnOnce + Clone (์บก์ฒ˜ ๋œ ๋ชจ๋“  ๋ณ€์ˆ˜๊ฐ€ Clone move ํด๋กœ์ €)
  • FnOnce + Copy + Clone (์บก์ฒ˜ ๋œ ๋ชจ๋“  ๋ณ€์ˆ˜๊ฐ€ Copy move ํด๋กœ์ €์ด๋ฏ€๋กœ Clone )
  • FnMut + FnOnce (๋ณ€ํ˜• ๋œ ์บก์ฒ˜ ๋ณ€์ˆ˜๊ฐ€์žˆ๋Š” ๋น„ move ํด๋กœ์ €)
  • Fn + FnMut + FnOnce + Copy + Clone (๋ณ€ํ˜• ๋œ ์บก์ฒ˜ ๋œ ๋ณ€์ˆ˜๊ฐ€์—†๋Š” ๋น„ move ํด๋กœ์ €)

๋”ฐ๋ผ์„œ ๊ฐ€๊นŒ์šด ์žฅ๋ž˜์— ์‚ฌ์–‘์„ ์‚ฌ์šฉํ•  ์ˆ˜์—†๋Š” ๊ฒฝ์šฐ Fn ํŠน์„ฑ์˜ ์ •์˜๋ฅผ ์—…๋ฐ์ดํŠธํ•˜์—ฌ Fn ๊ฐ€ FnOnce + Clone ๊ณผ ๊ฒน์น˜์ง€ ์•Š๋„๋กํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€๊ฐ€ Fn ์—†์ด 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://play.rust-lang.org/?gist=fc7cf5145222c432e2bd8de1b0a425cd&version=nightly&mode=debug

๋งž๋‚˜์š”? ๋‚ด ์˜ˆ์—๋Š” ๋นˆ impl์ด ์—†์Šต๋‹ˆ๋‹ค.

@glandium

 impl B for Foo {}

@MoSal ์ด์ง€๋งŒ B ๋Š” ๊ธฐ๋ณธ ๊ตฌํ˜„์œผ๋กœ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฏ€๋กœ "๋น„์–ด ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค".

@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 ๋…„ ๋™์•ˆ ์ง„์ „์ด์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค (์›๋ž˜ ๊ฒŒ์‹œ๋ฌผ์— ๋”ฐ๋ฅด๋ฉด). ๋žญ ํŒ€์ด ์ด๊ฑธ ํฌ๊ธฐ ํ–ˆ๋‚˜์š”?

@alexreg ์ตœ์‹  ๊ฐœ๋ฐœ์— ๋Œ€ํ•ด์„œ๋Š” http://aturon.github.io/2018/04/05/sound-specialization/ ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

@alexreg ๊ฑด ์ „ํ•จ์ด _hard_๋กœ ๋ฐํ˜€์กŒ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ํ˜„์žฌ ์ผ์–ด๋‚˜๊ณ ์žˆ๋Š” "ํ•ญ์ƒ ์ ์šฉ ๊ฐ€๋Šฅํ•œ impls"์•„์ด๋””์–ด์— ๋Œ€ํ•œ ์ž‘์—…์ด ์žˆ๋‹ค๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ง„์ „์ด ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/rust-lang/rust/pull/49624๋ฅผ ์ฐธ์กฐ

์•ฝ๊ฐ„์˜ ๋žญ ๊ธ€๋ง ํ›„์— specialization ๋ฐ overlapping_marker_traits ์‚ฌ์šฉํ•˜์—ฌ ํ•ดํ‚น์„ ํ†ตํ•ด ์ด๋ฏธ ๊ต์ฐจ impls๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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;
}


๋‚˜๋Š” ์ด๊ฒƒ์„ ์‹œ๋„ํ–ˆ๋‹ค :


Rust ์ฝ”๋“œ

#![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/ ์ฐธ์กฐ

๋‚ด ์ƒ๊ฐ ์—” ๋ชจ๋“  ์‚ฌ๋žŒ๋“ค์ด ์ง€๊ธˆ ์—๋””์…˜์— ์ง‘์ค‘ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค ...

๊ณ ๋งˆ์›Œ์š” ...์ด ๋ฌธ์ œ๋Š” ์˜์›ํžˆ ๊ณ„์†๋˜๋Š” ๊ฒƒ ๊ฐ™์ง€๋งŒ ์ถฉ๋ถ„ํžˆ ๊ณตํ‰ํ•ฉ๋‹ˆ๋‹ค. ํž˜๋“ค์–ด ์•Œ์•„. ์•ˆํƒ€๊น๊ฒŒ๋„ ์ง€๊ธˆ์€ ๋‹ค๋ฅธ ๊ณณ์œผ๋กœ์ฃผ์˜๋ฅผ ๊ธฐ์šธ์ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์™„์ „ ๋‹จ์ผ ํ˜•ํƒœ์˜ ๊ฒฝ์šฐ ๊ธฐ๋ณธ ๊ด€๋ จ ์œ ํ˜•์— ๋Œ€ํ•œ ํˆฌ์˜์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋ฅผ ๋” ๊ตฌ์ฒด์ ์œผ๋กœ ์„ค๋ช… ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ๊ทธ ๊ธฐ๋Šฅ์„ ์›ํ•˜๋Š” ์œ ์Šค ์ผ€์ด์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค (ํŠนํžˆ ์™„์ „ํžˆ ๋ชจ๋…ธ ๋ชจํ”ฝ์ด ์•„๋‹Œ ์œ ํ˜•์œผ๋กœ ํŠน์„ฑ์ด ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์€ ์˜๋ฏธ ์ƒ ์ž˜๋ชป๋˜์—ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค). ๊ฑด์ „์„ฑ ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๋ฉด ๊ทธ ์ด์œ ๋ฅผ ์™„์ „ํžˆ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@pythonesque https://github.com/rust-lang/rust/pull/42411์— ๋ช‡ ๊ฐ€์ง€ ํ† ๋ก ์ด

์•„, ํ”„๋กœ์ ์…˜ ์ด ์ผ๋ฐ˜์  ์œผ๋กœ ์ „๋ฌธํ™”์™€ ๋‚˜์˜๊ฒŒ ์ƒํ˜ธ ์ž‘์šฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ฐํ˜€์ง€๋ฉด ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค

๋ถˆํ–‰ํžˆ๋„ ๊ทธ๋Ÿฌํ•œ ๊ธฐ๋Šฅ์—†์ด ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๊ฒƒ์„ ํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŠน์ • ํŠน์„ฑ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋‘ ๊ฐœ์˜ ์ „๋‹ฌ ๋œ ์œ ํ˜•์ด ๊ตฌ๋ฌธ ์ ์œผ๋กœ ๋™์ผ ํ•  ๋•Œ "True"๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ์—ฐ๊ด€๋œ ์œ ํ˜•์„ ๊ฐ–๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ "False"( "False"์ผ€์ด์Šค๊ฐ€ "์˜๋ฏธ ์ ์œผ๋กœ"๋™์ผํ•œ ์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•  ์ˆ˜์žˆ๋Š” ๋” ๋น„์‹ผ ํŠน์„ฑ ๊ฒ€์ƒ‰์„ ํŠธ๋ฆฌ๊ฑฐ ํ•จ). ์œ ์ผํ•œ ๋Œ€์•ˆ์€ ํ•ญ์ƒ ๊ฐ’ ๋น„์‹ผ ๊ฒ€์ƒ‰์„ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ก ์ ์œผ๋กœ๋Š” ๊ดœ์ฐฎ์ง€ ๋งŒ ํ›จ์”ฌ ๋” ๋น„์Œ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(ํŠธ๋ ˆ์ด ํŠธ๊ฐ€ ๋‹ซํžˆ๋„๋ก ์˜๋„ ๋œ ๊ฒฝ์šฐ ํ—ค๋“œ ์œ„์น˜์— ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ์ƒ์„ฑ์ž ์Œ์„ ์—ด๊ฑฐํ•˜๊ณ  True ๋˜๋Š” False๋ฅผ ์ถœ๋ ฅํ•˜๋„๋กํ•˜์—ฌ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.ํ•˜์ง€๋งŒ ์ €์žฅ์†Œ ์™ธ๋ถ€์—์„œ ํ™•์žฅ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์—ด๋ ค ์žˆ์œผ๋ฏ€๋กœ ํŠนํžˆ ๋‘ ๊ฐœ์˜ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž ์ €์žฅ์†Œ์˜ ๊ตฌํ˜„์ด ๋ฐ˜๋“œ์‹œ ์„œ๋กœ์— ๋Œ€ํ•ด ์•Œ ํ•„์š”๋Š” ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.)

์–ด์จŒ๋“ , ์ด๊ฒƒ์€ ๋‚ด๊ฐ€ํ•˜๊ณ  ์‹ถ์€ ๊ฒƒ์ด ํŠน์„ฑ ์‹œ์Šคํ…œ์— ์ ํ•ฉํ•˜์ง€ ์•Š๋‹ค๋Š” ํ‘œ์‹œ ์ผ ๋ฟ์ด๋ฉฐ ๋งคํฌ๋กœ์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ๋ฉ”์ปค๋‹ˆ์ฆ˜์œผ๋กœ ์ „ํ™˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๊ฒƒ์ด "๋ถ€์ •์ ์ธ ์ถ”๋ก "ํ’๋ฏธ๋ผ๋Š” ๊ฒƒ์€ ์‚ฌ์‹ค์ž…๋‹ˆ๋‹ค (๋‹ซํžŒ ํŠน์„ฑ์œผ๋กœ๋Š” ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค).

๋ถ€์ •์ ์ธ ์ถ”๋ก ์— ๋Œ€ํ•œ ๋Œ€์•ˆ์€ ์œ ํ˜•์ด ๋‹ซํžŒ ํŠน์„ฑ ์ง‘ํ•ฉ ์ค‘ ํ•˜๋‚˜์˜ ํŠน์„ฑ ๋งŒ ๊ตฌํ˜„ํ•˜์—ฌ ์ง‘ํ•ฉ์—์žˆ๋Š” ๋‹ค๋ฅธ ํŠน์„ฑ๊ณผ์˜ ๊ตฌํ˜„์ด ๊ฒน์น  ์ˆ˜ ์—†๋„๋กํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค (์˜ˆ : 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 () ์—†์œผ๋ฏ€๋กœ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€์ด๋ฅผ ํ—ˆ์šฉํ•˜์ง€๋งŒ ๋‘ ๋ฒˆ์งธ ์˜ˆ์ œ์—์„œ๋Š” ๋‹ค์šด ์ŠคํŠธ๋ฆผ ํฌ๋ ˆ์ดํŠธ๊ฐ€ impl Bar<CustomType> for () ๊ฐ€ ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด๋Š” ๊ธฐ๋ณธ impl๊ณผ ์ถฉ๋Œํ•ฉ๋‹ˆ๋‹ค.

@Boscop ์ด ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ๊ธฐ๋ณธ impl์€ ์–ด์จŒ๋“  ์•„๋ž˜์˜ ๊ธฐ๋ณธ๊ฐ’์ด ์•„๋‹Œ ๊ฒƒ์œผ๋กœ ์žฌ์ •์˜๋˜์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค๋ฅธ impls ์•ž์— impl Bar<bool> for () {} ์ถ”๊ฐ€ํ–ˆ๋‹ค๋ฉด (RFC / ๊ธฐ๋Œ€์— ๋”ฐ๋ผ) ์ž‘๋™ ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋งž์ง€ ์•Š๋‚˜์š”?

๋‹น์‹ ์ด ์–ธ๊ธ‰ ํ•œ ๋ฐ˜๋ก€์˜ ํ–‰์„ ๋” ๊นŠ์ด ํŒŒ๊ณ  ๋“ค์–ด, ๋‚˜๋Š” ๊ทธ ์˜ˆ์ œ๊ฐ€ "ํ•ญ์ƒ ์ ์šฉ ๊ฐ€๋Šฅํ•œ" ํ…Œ์ŠคํŠธ๋ฅผ ๋งŒ์กฑํ•˜๊ณ  ์žˆ๊ณ  ์ž‘์—…์ค‘์ผ์ง€๋„ ๋ชจ๋ฅธ๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ซ๋Š”๋‹ค (๋˜๋Š” ๋ฏฟ๋Š”๋‹ค).

์ด ๋ฌธ์ œ๋Š” ์•„๋งˆ๋„ # 45814์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

์ „๋ฌธํ™”์—์—†๋Š” ๊ธฐ๋ณธ ํŠน์„ฑ ๊ฒฝ๊ณ„๋ฅผ ์ง€์›ํ•  ๊ณ„ํš์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๊ณต์œ ํ•ด์„œ๋Š” ์•ˆ๋˜๋Š” ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ์ž„์˜์˜ Inner๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ œ๋„ค๋ฆญ 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 ๊ฐ€ ํ•˜๋‚˜์˜ ๊ฒŒ์‹œ๋ฌผ์„ ๋™์ผํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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 ๋ฉ”์„œ๋“œ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ํŠน์ˆ˜ํ™” ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

@ 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 ๊ท€ํ•˜์˜ ์˜ˆ์ œ ( ๋†€์ดํ„ฐ )์—์„œ "์ถฉ๋Œํ•˜๋Š” ๊ตฌํ˜„"์˜ค๋ฅ˜๋ฅผ ์žฌํ˜„ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์—…๋ฐ์ดํŠธ : ์•„, ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค. ์˜ˆ์ œ๊ฐ€ ์ž‘๋™ํ•˜๋ ค๋ฉด Bar ํŠธ๋ ˆ์ด ํŠธ๊ฐ€ ์—…์ŠคํŠธ๋ฆผ ํฌ๋ ˆ์ดํŠธ์— ์žˆ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

@updogliu ์˜ˆ์ œ๋Š” Foo ์ด Error ๊ตฌํ˜„ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ „๋ฌธํ™”๋ฅผ ํ‘œ์‹œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์˜ค๋Š˜ ๋ฐค์— ๋„ˆ๋ฌด ๋Šฆ๊ฒŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•„์•ผํ•ฉ๋‹ˆ๊นŒ?

#![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๋ฅผ ๋ณด๋ฉด ๊ณ ์œ  ํ•œ impls์˜ ์ „๋ฌธํ™”์— ๋Œ€ํ•œ ์„น์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€ ๋‚ด๊ฐ€ ์‹œ๋„ ํ–ˆ์Šต๋‹ˆ๊นŒ?

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 ๋ฉ”์„œ๋“œ์˜ ๊ฒฝ์šฐ ์œ ํ˜•์— ๋Œ€ํ•œ ํŠน์„ฑ์˜ impls๊ฐ€ const impls ์—ฌ์•ผํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ์ ‘ํ•˜๊ณ  ์ƒํƒœ์— ๋Œ€ํ•ด ๊ถ๊ธˆํ•œ ์‚ฌ๋žŒ์„ ์œ„ํ•ด 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๊ฐ€ ๋‹ค์Œ ๊ณผ ๊ฐ™์ด

๋งŒ์กฑ์Šค๋Ÿฝ๊ฒŒ ํ•ด๊ฒฐ๋˜์ง€ ์•Š์€ ํ•˜๋‚˜์˜ ํ•ต์‹ฌ ๋ฌธ์ œ [์ „๋ฌธ ๋ถ„์•ผ]๊ฐ€์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ˆ˜๋ช…๊ณผ ํŠน์„ฑ์— ๋Œ€ํ•œ ๊ธฐ์ˆ ์  ๊ฑด์ „์„ฑ ๋ฌธ์ œ [...] ๊ทธ๋Ÿฐ ๋‹ค์Œ [์œ„์— ๋งํฌ ๋œ ๋‘ ๊ฒŒ์‹œ๋ฌผ]. ์ด๋Ÿฌํ•œ ์•„์ด๋””์–ด๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐ ํ•œ ๊ฒƒ ๊ฐ™์ง€๋งŒ ๊ทธ ๋™์•ˆ ๋ฐ”์˜๊ณ  ํ›„์† ์กฐ์น˜๋ฅผ ์ทจํ•  ์‹œ๊ฐ„์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

์•„์งํ•ด์•ผ ํ•  ์ผ์ด ๋ถ„๋ช…ํžˆ ๋‚จ์•„ ์žˆ์ง€๋งŒ ํฌ๋ง์ ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

(๋ช‡ ์ฃผ ์ „์—์ด ์Šค๋ ˆ๋“œ๋ฅผ ์ฐพ์•˜๊ณ  ์ž‘๋…„์˜ ์ง„ํ–‰ ์ƒํ™ฉ์„ ์ „ํ˜€ ๋ชฐ๋ž๊ธฐ ๋•Œ๋ฌธ์— ๊ฒŒ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. ์ตœ๊ทผ์— ์šฐ์—ฐํžˆ ํ•ด๋‹น ๊ฒŒ์‹œ๋ฌผ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์œ„์— ์–ธ๊ธ‰ ๋œ ๋Œ“๊ธ€์ด ์žˆ์ง€๋งŒ 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

@Hexilee impl์ด ์•„๋‹Œ ๋ฉ”์†Œ๋“œ์— default ์„ ๋„ฃ์œผ์‹ญ์‹œ์˜ค.

@KrishnaSannasi ์˜ˆ 2

@zserik ๋„ค, ์•Œ์•„์š”. ์•„์ง ๊ตฌํ˜„๋˜์ง€ ์•Š์•˜๊ฑฐ๋‚˜ ์‚ญ์ œ ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์–ด์จŒ๋“  ์ง€๊ธˆ์€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋ถ„๋ช…ํžˆ ์ง€๊ธˆ์€ ์ž‘๋™ํ•˜์ง€ ์•Š์ง€๋งŒ ์ž‘๋™ํ•ด์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ด ์ฃผ์ œ๊ฐ€ ๋‹ค๋ฅธ ๊ณณ์—์„œ ๋‚˜์˜ค์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์—์„œ ๋ฌป์Šต๋‹ˆ๋‹ค. default ์šฐ๋ฆฌ๊ฐ€ 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 ๋Œ€ํ•œ ์ „๋ฌธํ™”๋ฅผ ํ—ˆ์šฉํ•˜๋”๋ผ๋„ ๊ฒฉ์ž ๋ฌธ์ œ๋กœ ์ธํ•ด ์ผ๋ฐ˜ impls์— ๋„์›€์ด๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@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://play.rust-lang.org/?version=stable&mode=debug&edition= 2018 & gist = cc126b016ff62643946aebc6bab88c98

@Osspial ์Œ, ๊ธฐ๋ณธ impl์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹œ๋ฎฌ๋ ˆ์ด์…˜์„ ์‹œ๋„ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

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

๋ฐ˜๋ณตํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. From/Into impl์„ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ธฐ๋ณธ impl๋กœ ๋ณ€๊ฒฝํ•ด๋„ Into ๋Œ€ํ•œ ์ผ๋ฐ˜ impl์ด ๊ฐ€๋Šฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ( From ์˜ ์ผ๋ฐ˜ impls์—๋Š” ์˜ํ–ฅ์„์ฃผ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.)

์•ˆ๋…•ํ•˜์„ธ์š”, ํ˜„์žฌ ์ „๋ฌธํ™” โ€‹โ€‹๊ตฌํ˜„์— ์‹ฌ๊ฐํ•œ ๋ฒ„๊ทธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๋ช…๋ฐฑํ•œ ๋””์ž์ธ ๊ฒฐ์ •์ด๋”๋ผ๋„ ์šฐ๋ฆฌ๊ฐ€ ๊ฐ€์žฅ ๊ฐ•๋ ฅํ•œ ์ „๋ฌธํ™” ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜, ์ฆ‰ "๋ถˆํˆฌ๋ช… ํ•œ ์œ ํ˜•"(์ด๊ฒƒ์€ ๊ณต์‹์ ์ธ ์ด๋ฆ„์ด ์•„๋‹˜)์˜ ์ƒ์„ฑ ๊ฐ€๋Šฅ์„ฑ์„ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๊ฒŒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฒ„๊ทธ๋กœ ๋ถ„๋ฅ˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ํŒจํ„ด์€ Haskell ๋˜๋Š” Scala์™€ ๊ฐ™์€ ์œ ํ˜• ํด๋ž˜์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋‹ค๋ฅธ ์–ธ์–ด์—์„œ ๊ฐ€์žฅ ์›์‹œ์  ์ธ ๋นŒ๋”ฉ ๋ธ”๋ก ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.

์ด ํŒจํ„ด์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. 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๋กœ ๋งŒ๋“ค์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

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

๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์€ ๋งค์šฐ ๋‚˜์ฉ๋‹ˆ๋‹ค . 2 ๊ฐ€์ง€ ์œ ํ˜• ๋งŒ ์žˆ์œผ๋ฉด ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ WithID , WithLabel , WithCallback ์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” 10 ๊ฐœ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ๋ถˆํˆฌ๋ช… ์œ ํ˜• ์ •์˜๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ • ํ•ด๋ณด์‹ญ์‹œ์˜ค. ์ „๋ฌธํ™”์˜ ํ˜„์žฌ ๋™์ž‘์œผ๋กœ, ์šฐ๋ฆฌ๋Š” ์ •์˜ํ•ด์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค ... 1000 ๊ฐ€์ง€๊ฐ€ ๋„˜๋Š” ๋‹ค์–‘ํ•œ ํŠน์„ฑ ๊ตฌํ˜„! ์ฃผ์„ ์ฒ˜๋ฆฌ ๋œ ์ฝ”๋“œ๊ฐ€ ์Šน์ธ๋˜๋ฉด 10 ๊ฐœ์˜ ํŠธ๋ ˆ์ด ํŠธ ๊ตฌํ˜„ ๋งŒ ํ•„์š”ํ•˜๋ฉฐ ๊ฐ๊ฐ์˜ ์ƒˆ๋กœ์šด ์œ ํ˜•์„ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด ์ถ”๊ฐ€ ๊ตฌํ˜„ ํ•˜๋‚˜๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค .

๊ท€ํ•˜์˜ ์ฝ”๋“œ๊ฐ€ ์ „๋ฌธํ™”์™€ ์–ด๋–ค ๊ด€๋ จ์ด ์žˆ๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ #![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>> ๋‹ค๋ฃน๋‹ˆ๋‹ค.
  • ๋‘ ๋ฒˆ์งธ impl์€ WithID<WithLabel<A>> ๋ฐ WithLabel<WithLabel<A>> ๋‹ค๋ฃน๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ impls ์Œ์€ RFC ์˜ ๋‹ค์Œ ์ ˆ

์ „๋ฌธํ™”๊ฐ€ ์ผ๊ด€๋˜๋„๋ก ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ์ค‘๋ณต๋˜๋Š” ๋‘ ๊ฐœ์˜ impls I ๋ฐ J ๋Œ€ํ•ด I < J ๋˜๋Š” J < I ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ํ•˜๋‚˜๋Š” ๋‹ค๋ฅธ ๊ฒƒ๋ณด๋‹ค ๋” ๊ตฌ์ฒด์ ์ด์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์€ ๋„ˆ๋ฌด ๋•Œ๋ฌธ์— ๊ท€ํ•˜์˜ ๊ฒฝ์šฐ ์ง„์งœ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค HasLabel ์˜ IMPL WithLabel<WithLabel<A>> ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ํ•ด์„ ๋  ์ˆ˜๋Š”.

์ด ์‚ฌ๋ก€๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ฐฉ๋ฒ• ์€ RFC ์—์„œ๋„ ์ด๋ฏธ

๊ฒฉ์ž ๊ทœ์น™์ด ํ•ด๊ฒฐํ•˜๋Š” ์ œํ•œ์€ (๋™๊ธฐ ๋ถ€์—ฌ์— ์„ค๋ช… ๋œ๋Œ€๋กœ) ์ „๋ฌธํ™”์˜ ์ฃผ์š” ๋ชฉํ‘œ์— ๋น„ํ•ด ์ƒ๋‹นํžˆ ๋ถ€์ฐจ์ ์ด๋ฏ€๋กœ ๊ฒฉ์ž ๊ทœ์น™์ด ๋‚˜์ค‘์— ์ถ”๊ฐ€ ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ RFC๋Š” ํ˜„์žฌ ๊ฐ„๋‹จํ•œ ์ฒด์ธ ๊ทœ์น™์„ ๊ณ ์ˆ˜ํ•ฉ๋‹ˆ๋‹ค.

@qnighy , ์ƒ๊ฐํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  WithLabel<WithLabel<A>> ์˜ HasLabel impl์€ ๋‘ ๊ฐ€์ง€ ๋ฐฉ์‹์œผ๋กœ ํ•ด์„ ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ท€ํ•˜์˜ ๊ฒฝ์šฐ์—๋„ ์‹ค์ œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

WithLabel<WithLabel<A>> ์˜ ์ž…๋ ฅ์— ๋Œ€ํ•ด impl<T> HasLabel for WithLabel<T> ๋ฅผ 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 ์„ (๋ฅผ) ์ด์šฉํ•˜์—ฌ ๊ฒน์น˜๋Š” ๋น„ ๋งˆ์ปค ํŠน์„ฑ์„ ํ—ˆ์šฉ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ์ด ํ•ดํ‚น์—๋Š” ์„ธ ๊ฐ€์ง€ ํŠน์„ฑ์ด ๋” ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค (ํ•˜๋‚˜๋Š” ๋งˆ์ปค ํŠน์„ฑ์„ ๊ฑฐ์น˜๊ณ  ๋‘ ๊ฐœ๋Š” ์ „๋ฌธํ™”๋ฅผ ํ†ตํ•ด ์ง€์›Œ์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ํš๋“ํ•˜๊ธฐ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค).

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

@qnighy ์ด ๋ฒ„๊ทธ์— ๋Œ€ํ•œ ๋ณ„๋„์˜ ๋ฌธ์ œ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค : https://github.com/rust-lang/rust/issues/66041

์ข‹์•„์š”, ๋ฐฉ๊ธˆ auto traits ๊ฐ€ ์—ฌ๊ธฐ์„œ ํ•ด๊ฒฐ์ฑ…์ด ๋  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค (https://doc.rust-lang.org/nightly/unstable-book/language-features/optin-builtin-traits์— ๋”ฐ๋ผ. html) ๊ตฌ์กฐ์ฒด์˜ ๋ชจ๋“  ํ•„๋“œ์— ์ „ํŒŒ๋ฉ๋‹ˆ๋‹ค.

ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ Send ๋˜๋Š” Sync์™€ ๊ฐ™์€ ์ž๋™ ํŠน์„ฑ์€ ์œ ํ˜• ๋˜๋Š” ํฌํ•จ ๋œ ์œ ํ˜•์ด ๋ถ€์ • impl์„ ํ†ตํ•ด ๋ช…์‹œ ์ ์œผ๋กœ ์˜ตํŠธ ์•„์›ƒํ•˜์ง€ ์•Š๋Š” ํ•œ ๋ชจ๋“  ์œ ํ˜•์— ๋Œ€ํ•ด ์ž๋™์œผ๋กœ ๊ตฌํ˜„๋˜๋Š” ๋งˆ์ปค ํŠน์„ฑ์ž…๋‹ˆ๋‹ค.

ํŽธ์ง‘ํ•˜๋‹ค
@qnighy ์–ด๋–ป๊ฒŒ ๋“  ๋‹น์‹ ์ด ๋†€์ดํ„ฐ ๋งํฌ๋ฅผ ์ œ๊ณตํ–ˆ๋‹ค๋Š” ๊ฒƒ์„ ๊ฐ„๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค. โค๏ธ ์ •๋ง ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ž‘๋™ํ•˜๋ฉฐ์ด ์†”๋ฃจ์…˜์ด ์–ผ๋งˆ๋‚˜ ํ•ดํ‚ค์ธ์ง€์— ๋†€๋ž์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ์ด๋ฅผ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด ๋†€๋ž๊ณ  ์•ž์œผ๋กœ๋„์ด ๊ฐ€๋Šฅ์„ฑ์ด ์‚ฌ๋ผ์ง€์ง€ ์•Š๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค!

์ด๋Ÿฌํ•œ ์ƒํ™ฉ์—์„œ overlapping marker traits ์€ ์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ ์‚ฌ์šฉํ•  ์ˆ˜์žˆ๋Š” ์œ ์ผํ•œ ํ•ดํ‚น์ด์ง€๋งŒ, ๋ฏธ๋ž˜์—๋Š” ๋ถˆํˆฌ๋ช… ํ•œ ์œ ํ˜•์„ ํ‘œํ˜„ํ•˜๋Š” ๋” ์‰ฌ์šด ํ•ด๊ฒฐ์ฑ…์„ ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค (์ด์ „ ๊ฒŒ์‹œ๋ฌผ : 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์„ ํ˜ธ์ถœํ•˜๊ณ  ํŠน์ˆ˜ํ•œ ๋ณ€ํ˜•์ด ์žˆ๋Š”์ง€ ํ™•์ธ). ์•„๋งˆ๋„ ํ•˜๋‚˜๊ฐ€ ๋” ๋น ๋ฅด๋‹ค๋Š” ์ ์„ ์ œ์™ธํ•˜๊ณ  ๋‘ ๋ณ€ํ˜•์ด ๋™๋“ฑํ•˜๋‹ค๊ณ  ๋งํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์–ด๋–ค ๋ฒ„์ „์„ ์–ป๊ณ  ์žˆ๋Š”์ง€ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๊นŒ? ์ด ๊ฒฝ์šฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ ๋‹น์žฅ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋™์ผํ•œ impls ์„ธํŠธ๋กœ ๋‹ค๋ฅธ ํŠน์„ฑ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ง€๋งŒ fns๊ฐ€ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ ์ž์‹ ์„ ์•ˆ์‹ฌ์‹œํ‚ค๊ธฐ ์œ„ํ•ด.

์•„๋งˆ๋„ ํ•˜๋‚˜๊ฐ€ ๋” ๋น ๋ฅด๋‹ค๋Š” ์ ์„ ์ œ์™ธํ•˜๊ณ  ๋‘ ๋ณ€ํ˜•์ด ๋™๋“ฑํ•˜๋‹ค๊ณ  ๋งํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์–ด๋–ค ๋ฒ„์ „์„ ์–ป๊ณ  ์žˆ๋Š”์ง€ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๊นŒ? ์ด ๊ฒฝ์šฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ ๋‹น์žฅ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋งคํฌ๋กœ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด 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 {
    () => {};
}

๊ทธ๋Ÿฐ ๋‹ค์Œ ํŠน์ˆ˜ impl์—์„œ 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 ์ฐธ์กฐ)์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค.

๋ฟก ๋นต๋€จ

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์ž˜๋ชป๋œ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

์˜๋„ ํ•œ ์ฝ”๋“œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•„์‹ญ๋‹ˆ๊นŒ? ๋‚˜๋Š” ์ฒ˜์Œ์— default impl ์ด type Output = Self; ๋„ ์„ค์ •ํ•˜๋„๋ก ์˜๋„๋˜์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์ง€๋งŒ ์‹ค์ œ๋กœ ์ œ์•ˆ ๋œ RFC์—์„œ๋Š” ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค . ๊ทธ๋ ‡๋‹ค๋ฉด ์˜๋„๋Š” Output = T ๋ฐ”์šด๋“œ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์ด ์—ˆ์Šต๋‹ˆ๊นŒ?

@RalfJung min_specialization ๊ฐ€ ๋ฌธ์„œํ™” ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๊ฑด์ „์„ฑ ๋ฒ„๊ทธ๋ฅผ ์•Œ๊ณ ์žˆ๋Š” (๊ทธ๋ฆฌ๊ณ  ์•„๋งˆ๋„ ์•Œ๋ ค์ง€์ง€ ์•Š์€) ๊ธฐ๋Šฅ๋ณด๋‹ค ์ƒ์ž์— ์™„์ „ํžˆ ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์€ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ์œ„ํ—˜ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‘˜ ๋‹ค ์ข‹์ง€๋Š” ์•Š์ง€๋งŒ ์ ์–ด๋„ ํ›„์ž๋Š” ์ปดํŒŒ์ผ๋Ÿฌ ๋‚ด๋ถ€๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

# 71321 PR ์ด์™ธ์˜์ด ์ถ”์  ๋ฌธ์ œ์—์„œ min_specialization ๋Œ€ํ•œ ์–ธ๊ธ‰์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค . Unstable ์ฑ…์— ๋”ฐ๋ฅด๋ฉด ์ด๊ฒƒ์ด ํ•ด๋‹น ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ถ”์  ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

์ €๋„ ๊ทธ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ๋งŽ์ด ์•Œ์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๋ฐฉ๊ธˆ libstd ๊ฑด์ „์„ฑ ์ˆ˜์ •์„ ๋ณด์•˜์Šต๋‹ˆ๋‹ค. https://github.com/rust-lang/rust/pull/68970์— ์†Œ๊ฐœ๋˜์–ด ๋ช‡ ๊ฐ€์ง€ ๋” ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

@matthewjasper ๊ฐ€ ์ด๊ฒƒ์„ ์กฐ๊ธˆ ๋” ๋ฌธ์„œํ™”ํ•˜๊ณ  feature(specialization) ์˜ ์•ผ๊ฐ„ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ž…๋‹ˆ๊นŒ?

์ตœ์†Œํ•œ ๊ฒฝ๊ณ ๊ฐ€ ์žˆ์–ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ๋…ธ๊ณจ์ ์œผ๋กœ ์†์ƒ๋˜์–ด ํ˜„์žฌ ์ƒํƒœ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ์— ์œ„ํ—˜ํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

specialization ๋Š” min_specialization ์˜ ๋™์˜์–ด๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ PyO3 ๋“ฑ๊ณผ ๊ฐ™์€ ๊ธฐ์กด ํ”„๋กœ์ ํŠธ์— ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋‹ค๋ฅธ unsound_specialization ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. min_specialization ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ์€ ๋ˆ„๊ตฌ๋‚˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์€ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›๊ณ  ์—ฌ๊ธฐ์—์„œ ์ƒˆ ์ด๋ฆ„์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฟก๋ฟก

์˜๋„ ํ•œ ์ฝ”๋“œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•„์‹ญ๋‹ˆ๊นŒ?

๊ธ€์Ž„, ์–ด๋Š ์‹œ์ ์—์„œ ์šฐ๋ฆฌ๋Š” ๊ธฐ๋ณธ๊ฐ’์ด ์„œ๋กœ ์˜์กด ํ•  ์ˆ˜์žˆ๋Š” ๋ชจ๋“œ๋ฅผ ๊ณ ๋ คํ•˜๊ณ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋‚˜๋Š” ๊ทธ ์‹œ์ ์—์„œ ๋‹ค์Œ์ด ํšจ๊ณผ๊ฐ€ ์žˆ์—ˆ์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ์ƒํ•ฉ๋‹ˆ๋‹ค.

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;
    }
}

์ฃผ์˜ํ•ด์•ผ ํ•  ์ ์€ ๋‹น์‹ ์ด์˜ ๊ตฌ์„ฑ์› ์˜ค๋ฒ„๋ผ์ด๋“œ (override)ํ•˜๋Š” ๊ฒฝ์šฐ ๊ฒƒ์ด ์—ˆ์Šต๋‹ˆ๋‹ค impl , ๋‹น์‹ ์€ ๊ทธ๋“ค ๋ชจ๋‘๋ฅผ ๋ฌด์‹œํ–ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋‚˜์ค‘์—์ด ์•„์ด๋””์–ด์—์„œ ๋ฌผ๋Ÿฌ๋‚˜ "๊ธฐ๋ณธ ๊ทธ๋ฃน"(์—ฌ๊ธฐ์„œ๋„ ์ž‘๋™ ํ•จ)๊ณผ ๊ฐ™์€ ๋‹ค์–‘ํ•œ ๋ฐ˜๋ณต ์ž‘์—…์„ ์‹œ์ž‘ํ–ˆ๊ณ  ๊ฒฐ๊ตญ์—๋Š” ์ฒ˜๋ฆฌ ํ•œ ํ›„ ๋‚˜์ค‘์— ์–ป์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋–ค ์†”๋ฃจ์…˜๋„ ์ฑ„ํƒํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ๊ธด๊ธ‰ํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค (cc # 71420).

๊ทธ๋Ÿฌ์ง€ ๋งˆ์‹ญ์‹œ์˜ค. PyO3 (Python ๋ฐ”์ธ๋”ฉ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)๋Š” ํ˜„์žฌ ์ „๋ฌธํ™”์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค. PyO3 / pyo3 # 210 ์ฐธ์กฐ

PyO3 ๋ฉ”์ธํ…Œ์ด๋„ˆ-์šฐ๋ฆฌ๋Š” ์•ˆ์ •์ ์ธ Rust์— ๋„๋‹ฌ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ „๋ฌธํ™”์—์„œ ๋ฒ—์–ด๋‚˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€ ์ „๋ฌธํ™”๊ฐ€ ์™„๋ฃŒ๋˜๊ธฐ ์ „์— min_specialization ์ด ์•ˆ์ •ํ™” ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

2021 ๋…„ ์—๋””์…˜ ๊ธฐํš ๋žญ ๋””์ž์ธ ํšŒ์˜์—์„œ min_specialization ์•ˆ์ •ํ™”์— ๋Œ€ํ•œ ๋…ผ์˜๊ฐ€ ์žˆ์—ˆ๋˜ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. (์œ ํŠœ๋ธŒ์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฏธ์•ˆ ํ•ด์š”, ์ œ ์ „ํ™”์— ์žˆ์–ด์š”, ์•„๋‹ˆ๋ฉด ๋งํฌ๋ฅผ ์ฐพ ๊ฒ ์–ด์š”) ๋‚˜๋Š” ๊ทธ๋“ค์ด ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ๋งํ•œ ๊ฒƒ์„ ์žŠ์—ˆ๋‹ค

2021 ๋…„ ์—๋””์…˜ ๊ธฐํš ๋žญ ๋””์ž์ธ ํšŒ์˜์—์„œ min_specialization ์•ˆ์ •ํ™”์— ๋Œ€ํ•œ ๋…ผ์˜๊ฐ€ ์žˆ์—ˆ๋˜ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. (์œ ํŠœ๋ธŒ์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฏธ์•ˆ ํ•ด์š”, ์ œ ์ „ํ™”์— ์žˆ์–ด์š”, ์•„๋‹ˆ๋ฉด ๋งํฌ๋ฅผ ์ฐพ ๊ฒ ์–ด์š”) ๋‚˜๋Š” ๊ทธ๋“ค์ด ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ๋งํ•œ ๊ฒƒ์„ ์žŠ์—ˆ๋‹ค

์ด๊ฒƒ์ด ์˜ฌ๋ฐ”๋ฅธ YouTube ๋งํฌ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค : https://youtu.be/uDbs_1LXqus
(๋‚ด ํœด๋Œ€ ์ „ํ™”์—์„œ๋„)

๋„ค, ๊ทธ๊ฒŒ ๋‹ค์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ํŠน์ • ํ† ๋ก ์— ๋Œ€ํ•œ ๋งํฌ์ž…๋‹ˆ๋‹ค. https://youtu.be/uDbs_1LXqus?t=2073

๊ฐœ๋ฐœ์ค‘์ธ ์‹คํ—˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ #[min_specialization] ์„ (๋ฅผ) ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฝํ—˜์„ ๊ณต์œ  ํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ชฉํ‘œ๋Š” ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ํ˜•ํƒœ๋กœ ์ „๋ฌธํ™”๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ๋ณด๋‹ค ๋” ๋น ๋ฅธ ๊ตฌํ˜„์œผ๋กœ ์ข์€ ๊ฒฝ์šฐ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํŠนํžˆ ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ ์•”ํ˜ธํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ผ์ •ํ•œ ์‹œ๊ฐ„์— ์‹คํ–‰ํ•˜์ง€๋งŒ ๋ชจ๋“  ์ž…๋ ฅ์ด Public ๋กœ ํ‘œ์‹œ๋˜์–ด ๋” ๋น ๋ฅธ ๊ฐ€๋ณ€ ์‹œ๊ฐ„์œผ๋กœ ์‹คํ–‰๋˜๋Š” ํŠน์ˆ˜ ๋ฒ„์ „์„ ๊ฐ–๋„๋กํ•˜๋ ค๋ฉด (๊ณต๊ฐœ ๋œ ๊ฒฝ์šฐ์—๋Š” ์‹คํ–‰ ์‹œ๊ฐ„์„ ํ†ตํ•ด ์ •๋ณด๋ฅผ ์œ ์ถœํ•˜๋Š” ๋ฐ ์‹ ๊ฒฝ์„ ์”๋‹ˆ๋‹ค). ๋˜ํ•œ ์ผ๋ถ€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ํƒ€์› ๊ณก์„  ์ ์ด ์ •๊ทœํ™”๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ๋” ๋น ๋ฆ…๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ์ž‘๋™์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์šฐ๋ฆฌ๋Š”

#![feature(rustc_attrs, min_specialization)]

๊ทธ๋Ÿฐ ๋‹ค์Œ ์ตœ๋Œ€ ์ตœ์†Œ ์ „๋ฌธํ™”์— ์„ค๋ช… ๋œ๋Œ€๋กœ _specialization predicate_ ํŠน์„ฑ์„ ๋งŒ๋“ค์–ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ํŠน์„ฑ ์„ ์–ธ์„ #[rustc_specialization_trait] ํ•ฉ๋‹ˆ๋‹ค.

๋‚ด ๋ชจ๋“  ์ „๋ฌธํ™”๋Š” ์ด ํŒŒ์ผ ์—์„œ ์ˆ˜ํ–‰๋˜๋ฉฐ ์—ฌ๊ธฐ ์— ์ „๋ฌธํ™” ์ˆ ์–ด ํŠน์„ฑ

์ด ๊ธฐ๋Šฅ์€ ์ž‘๋™ํ•˜๋ฉฐ ํ•„์š”ํ•œ ์ž‘์—…์„ ์ •ํ™•ํžˆ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ถ„๋ช…ํžˆ rustc ๋‚ด๋ถ€ ๋งˆ์ปค๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ๊ฒฝ๊ณ ์—†์ด ๊นจ์ง€๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.

์œ ์ผํ•œ ๋ถ€์ •์ ์ธ ํ”ผ๋“œ๋ฐฑ์€ default ํ‚ค์›Œ๋“œ๊ฐ€ ๋ง์ด๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ณธ์งˆ์ ์œผ๋กœ default ๊ฐ€ ํ˜„์žฌ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์€ "์ด impl์€ ํŠน์ˆ˜ํ™” ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ ์ถฉ๋Œํ•˜๋Š” impl์ด ์•„๋‹ˆ๋ผ์ด ํ•˜๋‚˜์˜ ํ•˜์œ„ ์ง‘ํ•ฉ์„ ํฌํ•จํ•˜๋Š” impl์„ ํ•ด์„ํ•ฉ๋‹ˆ๋‹ค"์ž…๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ๋งค์šฐ ์ด์ƒํ•œ ์ฝ”๋“œ๋กœ ์ด์–ด์ง„๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

์—ฌ๊ธฐ์„œ ๋‘ ๋ฒˆ์งธ impl์€ ์ฒซ ๋ฒˆ์งธ๋ฅผ ์ „๋ฌธํ™”ํ•˜๊ณ  ์žˆ์ง€๋งŒ default ์ด๊ธฐ๋„ํ•ฉ๋‹ˆ๋‹ค. default ์˜ ์˜๋ฏธ๊ฐ€ ์†์‹ค ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€ impls๋ฅผ ์‚ดํŽด๋ณด๋ฉด ์–ด๋–ค 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 ์—†์ด ๊ตฌํ˜„ ๋  ์ˆ˜ ์žˆ์ง€๋งŒ ๋‘ ์œ ํ˜•์ด ์„œ๋กœ ๋‹ค๋ฅธ Output ์œ ํ˜•๊ณผ ๊ณต์กดํ•˜๋Š” ๊ฒƒ์„ ์›ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. IndexSet ๋Š” IndexMut ์ธก๋ฉด์—์„œ ๊ธฐ๋ณธ ๊ตฌํ˜„์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ Output ํŠน์ˆ˜ํ™”๋ฅผ ํ—ˆ์šฉํ•˜์ง€ ์•Š๊ณ  index_set ๋ฉ”์„œ๋“œ์˜ ํŠน์ˆ˜ํ™”๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ž…๋‹ˆ๋‹ค.

๋™์˜์ƒ์ด ๋„ˆ๋ฌด ์–ด๋ ค์›Œ์„œ ๋งํฌ ๋œ ๋™์˜์ƒ์„ ์ฐพ์„ ์ˆ˜ ์—†์ง€๋งŒ #[min_specialization] ๋Œ€ํ•œ ์งˆ๋ฌธ์ด ํ•˜๋‚˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์žˆ๋Š” ๊ทธ๋Œ€๋กœ ์ตœ์ ํ™” ํžŒํŠธ๋ฅผ ์ œ๊ณตํ•˜๋Š” FusedIterator ์™€ ๊ฐ™์€ ํŠน์„ฑ์— ๋Œ€ํ•œ rustc_unsafe_specialization_marker ์†์„ฑ์ด ์žˆ์œผ๋ฏ€๋กœ ํŠน์ˆ˜ํ™” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @matthewjasper ๋Š” ๋‹ค์Œ

์ด๊ฒƒ์€ ๋ถˆ๊ฑด์ „ํ•˜์ง€๋งŒ ํŠน์„ฑ ๋ฉ”์„œ๋“œ๋ฅผ ์ „๋ฌธํ™”ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ˆœ์ „ํžˆ ์•ˆ์ „ํ•œ ์ฝ”๋“œ๋กœ frees ํ›„์— ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋‹จ๊ธฐ์ ์œผ๋กœ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.

๊ณ„ํš์€ @aturon ์˜ ์ œ์•ˆ์„ ๊ตฌํ˜„ํ•˜๊ณ  ์ด๋Ÿฌํ•œ ํŠน์„ฑ ( where specialize(T: FusedIterator) )์— ๋Œ€ํ•œ ์ „๋ฌธํ™” ์–‘์‹์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ˜„์žฌ๋Š” ๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ์ด๋Ÿฌํ•œ ํŠน์„ฑ์— ํŠนํ™” ํ•  ์ˆ˜์žˆ๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ์žˆ๋Š” ๊ทธ๋Œ€๋กœ ์•ˆ์ •ํ™”๋˜๋ฉด ์‚ฌ๋žŒ๋“ค์€ ๊ทธ๊ฒƒ์— ์˜์กดํ•˜๋Š” ์•ˆ์ •์ ์ธ ์ „๋ฌธํ™”๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰,์ด ๋ถˆ๊ฑด์ „ ํ•จ์ด ์•ˆ์ •ํ™” ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์ด๋Ÿฌํ•œ ํŠน์„ฑ์— ๋Œ€ํ•œ ์ „๋ฌธํ™”๋„ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์ œํ•œ๋˜์–ด์•ผํ•ฉ๋‹ˆ๊นŒ? ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ „๋ฌธํ™” ํ•  ์ˆ˜์žˆ๋Š” ์ด์ ์„ ์ถฉ๋ถ„ํžˆ ์–ป์Šต๋‹ˆ๊นŒ?

์žˆ๋Š” ๊ทธ๋Œ€๋กœ ์•ˆ์ •ํ™”๋˜๋ฉด ์‚ฌ๋žŒ๋“ค์€ ๊ทธ๊ฒƒ์— ์˜์กดํ•˜๋Š” ์•ˆ์ •์ ์ธ ์ „๋ฌธํ™”๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰,์ด ๋ถˆ๊ฑด์ „ ํ•จ์ด ์•ˆ์ •ํ™” ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

min_specialization ๊ทธ๋Œ€๋กœ ์•ˆ์ •ํ™”๋ฅผ์œ„ํ•œ ๊ฒƒ์ด ์•„๋‹˜์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋‘ ๋ฒˆ์งธ๋กœ impls ์ „๋ฌธํ™”์— ๋Œ€ํ•œ ์ผ์ข…์˜ ๋งˆ์ปค๋ฅผ ๊ฐ–๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. 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๋Š” ํŠน์ˆ˜ํ™” impls๊ฐ€ ํ‘œ์‹œ๋˜์ง€ ์•Š์•˜๋‹ค๋Š” ์‚ฌ์‹ค์„ ํ†ตํ•ด ๋‹ด์š” impls์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํ”ผํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด default impl<T> Trait for T ๋Š” ๋‹ค์šด ์ŠคํŠธ๋ฆผ impls์™€ ์ถฉ๋Œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ‘œ์‹œ๋ฅผ ํ•ด์ œํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ๊ฒฝ๊ณ ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

rustc์—์„œ ์ฝ”๋“œ์˜ ๊ฒฝ์šฐ๊ฐ€ ๊ฝค ๋งŽ์•˜๊ณ , ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ „๋ฌธํ™”๊ฐ€ ์‹ค์ œ๋กœ ์ผ์–ด๋‚˜๊ณ  ์žˆ์Œ์„ ์•Œ ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋ณด์ด๋Š”๋Œ€๋กœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Java์— ๋Œ€ํ•œ ๋‚˜์˜ ๊ฒฝํ—˜์€ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค (์ •ํ™•ํžˆ ์œ ์‚ฌํ•˜์ง€๋Š” ์•Š์ง€๋งŒ). ํด๋ž˜์Šค์˜ ์–ด๋–ค ์„œ๋ธŒ ํด๋ž˜์Šค๊ฐ€ ์‹ค์ œ๋กœ ์‹คํ–‰ ์ค‘์ธ์ง€ ์•Œ์•„ ๋‚ด๊ธฐ๊ฐ€ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์ฝ์„ ๋•Œ ๋ช…ํ™•์„ฑ์„ ์œ„ํ•ด ํŠน์ˆ˜ํ™” ๊ฐ€๋Šฅํ•œ ๋‹จ์ˆœํ™”์—๋„ ๋งˆ์ปค๋ฅผ ์›ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋งˆ์ปค๋ฅผ ๋‘ ์œ„์น˜์— ๋‘˜ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์ด์ œ ์ „๋ฌธํ™”๊ฐ€ ํ•„์š”ํ•œ์ง€ ์—ฌ๋ถ€๋ฅผ ์•Œ๊ณ  ์žˆ๊ณ  ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค๋ฅธ ์œ„์น˜๋ฅผ ๊ฐ€๋ฆฌํ‚ฌ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— rustc ์˜ค๋ฅ˜ ๋˜๋Š” ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๊ฐ€ ๊ฐœ์„ ๋ฉ๋‹ˆ๋‹ค.

์—…์ŠคํŠธ๋ฆผ ํฌ๋ ˆ์ดํŠธ๊ฐ€ impl์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋‹จ์ˆœํžˆ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๊ฒƒ ์™ธ์—๋„ ๋‹ค์šด ์ŠคํŠธ๋ฆผ ํฌ๋ ˆ์ดํŠธ๋Š” ์ƒˆ ๋ฒ„์ „๊ณผ ์ด์ „ ๋ฒ„์ „ ๋ชจ๋‘์— ๋Œ€ํ•ด ์ปดํŒŒ์ผ์„ ํ—ˆ์šฉํ•˜๋Š” ํŠธ๋ฆญ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ทธ๊ฒŒ ์œ ์ตํ• ์ง€ ํ™•์‹  ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ฐจ์ด๊ฐ€ ๋„ˆ๋ฌด ์ปค์„œ ๋ณ€ํ™”๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค : https://github.com/rust-lang/rust/blob/fb818d4321dee29e1938c002c1ff79b0e7eaadff/src/librustc_span/def_id.rs#L124

Re : Blanket impls, ๊ทธ๋“ค์€ ์–ด์จŒ๋“  ๋ณ€ํ™”๋ฅผ ๊นจ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค :

  • ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š” ๋‹ค์šด ์ŠคํŠธ๋ฆผ impl๊ณผ ๋ถ€๋ถ„์ ์œผ๋กœ ๊ฒน์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ผ๊ด€์„ฑ์€ ๋” ๋ฏธ๋ฌ˜ํ•œ ๋ฐฉ์‹์œผ๋กœ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ๊ฐ€์ • ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (์ด๊ฒƒ์ด ์˜ˆ์•ฝ impls๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ์ถ”๊ฐ€ ๋œ ์ด์œ ์ž…๋‹ˆ๋‹ค).
  • ํŠน์ˆ˜ํ™” ๋‹จ์ˆœํ™”๋Š” ํ•ญ์ƒ ์ ์šฉ ๊ฐ€๋Šฅํ•ด์•ผํ•˜๋ฉฐ, ์ด๋Š” ๋‹ค์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

    • ์šฐ๋ฆฌ๋Š” ์‚ฌ๋žŒ๋“ค์˜ ๋‹จ์ˆœํ™”๋ฅผ ๊นจ๋œจ๋ฆฝ๋‹ˆ๋‹ค ( min_specialization ๊ฐ€ํ•˜๋Š” ์ผ).

    • ํ•„์š”ํ•œ ๊ณณ์— ํ•ญ์ƒ ์ ์šฉ ๊ฐ€๋Šฅํ•˜๋„๋ก ํŠน์„ฑ ๊ฒฝ๊ณ„์— ์ฃผ์„์„ ๋‹ฌ๋„๋ก ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค.

    • ํ•ญ์ƒ ์ ์šฉ ๊ฐ€๋Šฅํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์•”์‹œ ์ ์œผ๋กœ ์ ์šฉํ•˜๊ณ  ๊ธฐ๋ณธ impl์ด ์ ์šฉ๋˜๋ฉด ์ž ์žฌ์ ์œผ๋กœ ๋ฏธ๋ฌ˜ํ•œ ๋Ÿฐํƒ€์ž„ ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@cuviper ์‚ฌ์‹ค, ๋‚˜๋Š” ์ „๋ฌธํ™”๋ฅผํ•˜๋”๋ผ๋„ ์ƒˆ๋กœ์šด ๋‹ด์š” impls๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ด€๋ จํ•˜์—ฌ ์—ฌ์ „ํžˆ ๊ฐ€์žฅ์ž๋ฆฌ ์ผ€์ด์Šค๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. impl<T: Copy> Clone for T { } imp๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ์•Œ์•„ ๋‚ด๋ ค๊ณ ํ–ˆ๋˜ ๊ธฐ์–ต ์ด๋‚ฉ๋‹ˆ๋‹ค . ์–ด์จŒ๋“ 

์–ด์จŒ๋“  #[override] ์ฃผ์„์ด ์—†๋‹ค๋Š” Lint ๊ฒฝ๊ณ ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฆ‰, ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋–ค impls๋ฅผ ์ „๋ฌธํ™”ํ•˜๊ณ  ์žˆ๋Š”์ง€ ์„ ์–ธํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด (์–ด๋–ป๊ฒŒํ• ์ง€ ๋ชจ๋ฅด๊ฒ  ์Œ) ๋ช‡ ๊ฐ€์ง€๋ฅผ ๋‹จ์ˆœํ™” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ impls ์‚ฌ์ด์˜ ๊ด€๊ณ„๋ฅผ ์ถ”๋ก ํ•ด์•ผํ•˜๋Š”๋ฐ ํ•ญ์ƒ ์•ฝ๊ฐ„ ๊นŒ๋‹ค ๋กญ์Šต๋‹ˆ๋‹ค.

์ดˆํฌ ํ”„๋กœ์ ํŠธ์—์„œํ•ด์•ผ ํ•  ๋ณด๋ฅ˜์ค‘์ธ ํ•ญ๋ชฉ ์ค‘ ํ•˜๋‚˜๋Š” ๋‹ค์‹œ ๋Œ์•„๊ฐ€์„œ ์ „๋ฌธํ™”๊ฐ€ ์–ด๋–ป๊ฒŒ ํ‘œํ˜„๋˜์–ด์•ผํ•˜๋Š”์ง€ ์ฒ ์žํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

rustc์—์„œ ์ฝ”๋“œ์˜ ๊ฒฝ์šฐ๊ฐ€ ๊ฝค ๋งŽ์•˜๊ณ , ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ „๋ฌธํ™”๊ฐ€ ์‹ค์ œ๋กœ ์ผ์–ด๋‚˜๊ณ  ์žˆ์Œ์„ ์•Œ ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋ณด์ด๋Š”๋Œ€๋กœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Java์— ๋Œ€ํ•œ ๋‚˜์˜ ๊ฒฝํ—˜์€ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค (์ •ํ™•ํžˆ ์œ ์‚ฌํ•˜์ง€๋Š” ์•Š์ง€๋งŒ). ํด๋ž˜์Šค์˜ ์–ด๋–ค ์„œ๋ธŒ ํด๋ž˜์Šค๊ฐ€ ์‹ค์ œ๋กœ ์‹คํ–‰ ์ค‘์ธ์ง€ ์•Œ์•„ ๋‚ด๊ธฐ๊ฐ€ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ง€๋‚œ 5 ์›”์— ํ•„์ž๋Š” ์‹ค์ œ๋กœ ๊ฒน์น˜๋Š” impls์— ์˜์กดํ•˜์ง€ ์•Š๊ณ  ๋Œ€์‹  type ๋งค๊ฐœ ๋ณ€์ˆ˜์—์„œ where match ์— ๋‹จ์ผ impl์„ ํ—ˆ์šฉํ•˜๋Š” 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 ๋Œ€ํ•œ ์ด๋Ÿฌํ•œ impl์€ ๋‹ค๋ฅธ ํŠธ๋ ˆ์ด ํŠธ 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"
}

์ด ๊ณต์‹์€ ์ ์šฉ ๊ฐ€๋Šฅํ•œ impls์˜ ์ˆœ์„œ๋ฅผ ์„ ํƒํ•˜๊ธฐ ์œ„ํ•ด ์—…์ŠคํŠธ๋ฆผ์— ๋” ๋งŽ์€ ์ œ์–ด๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ ์ด๊ฒƒ์ด ํŠน์„ฑ / ๊ธฐ๋Šฅ ์„œ๋ช…์˜ ์ผ๋ถ€์ด๋ฏ€๋กœ ๋ฌธ์„œ์— ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. IMO๋Š” ํ•ด๊ฒฐ ์ˆœ์„œ๊ฐ€ ๋ช…์‹œ ์ ์ด๋ฏ€๋กœ ์‹ค์ œ๋กœ ์ ์šฉ ํ•  ์ˆ˜์žˆ๋Š” ๋ถ„๊ธฐ๋ฅผ ์•Œ๊ธฐ์œ„ํ•œ "๊ฐ„๋‹จํ•œ ์ถ”์ "์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์ „๋ฌธํ™”๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋™์•ˆ ์—…์ŠคํŠธ๋ฆผ์—์„œ๋งŒ ๋งŒ๋‚  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ˆ˜๋ช…๊ณผ ์œ ํ˜• ํ‰๋“ฑ์— ๋Œ€ํ•œ ์˜ค๋ฅ˜๋ฅผ ๋” ๋ถ„๋ช…ํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (๋‹ค์šด ์ŠคํŠธ๋ฆผ์€ "ํŠน์ˆ˜ํ™” ํŠน์„ฑ"๋งŒ ๊ตฌํ˜„ํ•˜๊ธฐ ๋•Œ๋ฌธ์—).

์ด ๊ณต์‹์˜ ๋‹จ์ ์€ RFC์˜ ๊ฒฝ๋กœ์™€ ๋งค์šฐ ๋‹ค๋ฅธ ๊ฒฝ๋กœ์ด๋ฉฐ 2016 ๋…„๋ถ€ํ„ฐ ๊ตฌํ˜„๋˜๊ณ  ์žˆ์œผ๋ฉฐ ์Šค๋ ˆ๋“œ์˜ ์ผ๋ถ€ ์‚ฌ๋žŒ๋“ค์ด ํ˜„์žฌ๋งŒํผ ํ‘œํ˜„ ์ ์ด๊ฑฐ๋‚˜ ์ง๊ด€์ ์ด์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๋Š” ์šฐ๋ ค๋ฅผ ํ‘œ๋ช…ํ–ˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ „๋ฌธํ™” ๊ธฐ๋Šฅ ( "์œ ํ˜• ์ผ์น˜"๊ฐ€ ๋งค์šฐ ์ง๊ด€์ ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ๊ณต์‹์„ ์ œ์•ˆ ํ•  ๋•Œ ํŽธํ–ฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค).

์ผ์น˜ ๊ตฌ๋ฌธ์€ ๋˜ ๋‹ค๋ฅธ (๊ตฌ๋ฌธ ์ ) ์ด์ ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๊ทธ๊ฒƒ์ด ๋ฏธ๋ž˜์˜ ์–ด๋Š ์‹œ์ ์— const ํ‰๊ฐ€ ๋งค์น˜ ๊ฐ€๋“œ๋กœ ํ™•์žฅ๋œ๋‹ค๋ฉด, const ํ‘œํ˜„์‹์— ์กฐ๊ฑด๋ถ€ ๊ฒฝ๊ณ„๋ฅผ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ํƒ€์ž… ์ฒด์กฐ๋ฅผ ํ•  ํ•„์š”๊ฐ€ ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด size_of , align_of , needs_drop ๋˜๋Š” ๋ฐฐ์—ด ํฌ๊ธฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ „๋ฌธํ™”๋ฅผ ์ ์šฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@dureuill ์ •๋ณด ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ์ฐธ์œผ๋กœ ํฅ๋ฏธ๋กœ์šด ์•„์ด๋””์–ด์ž…๋‹ˆ๋‹ค. ํ•œ ๊ฐ€์ง€ ์šฐ๋ ค๋˜๋Š” ์ ์€ ์ „๋ฌธํ™”์— ๋Œ€ํ•ด ์˜ˆ์ƒ๋˜๋Š” ๋‹ค๋ฅธ ์‚ฌ์šฉ ์‚ฌ๋ก€ ์ค‘ ์ผ๋ถ€, ํŠนํžˆ์ด ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ ์—์„œ @aturon ์ด ์„ค๋ช…ํ•œ "์ ์ง„์ ์œผ๋กœ ๊ฐœ์„ ํ•˜๋Š” ๋™์ž‘"์‚ฌ๋ก€๋ฅผ ๋ฐ˜๋“œ์‹œ ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ ๋ช…์‹ฌํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

@dureuill ์•„์ด๋””์–ด๋Š” ์ฐธ์œผ๋กœ ํฅ๋ฏธ๋กญ๊ณ  ๋งŽ์€ ์ž ์žฌ๋ ฅ์„ ๊ฐ€์ง€๊ณ ์žˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ ๋Œ€์•ˆ์ด ํ•ญ์ƒ ๋™๋“ฑํ•œ ๊ตํ™˜์€ ์•„๋‹™๋‹ˆ๋‹ค.
๋‚ด๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ์ƒ๊ฐํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š”๋ณด๋‹ค ์ผ๋ฐ˜์ ์ธ ๊ตฌํ˜„์„ ์™„์ „ํžˆ ๋Œ€์ฒด ํ•  ๊ธฐํšŒ๊ฐ€ ์ฃผ์–ด์ง€์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ๋Š” ๊ท€ํ•˜์˜ ์ œ์•ˆ์ด ์˜์กดํ•˜๋Š” where ๊ตฌ๋ฌธ RFC์—์žˆ๋Š” ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ์‹ค์ œ๋กœ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์‚ฌ์‹ค์ž…๋‹ˆ๋‹ค.
์ด ์ œ์•ˆ์€ ํฅ๋ฏธ ๋กญ๊ธฐ ๋•Œ๋ฌธ์— ๋‘˜ ๋‹ค ์œ ์šฉํ•˜๊ณ  ํ•จ๊ป˜ ์‚ด ์ˆ˜์—†๋Š” ์ด์œ ๋ฅผ ์•Œ์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ „๋ฌธํ™” ๊ฒฝ์Ÿ์ž๊ฐ€ ์•„๋‹Œ ๋ณ„๋„์˜ ๊ธฐ๋Šฅ์œผ๋กœ ์ž์ฒด RFC๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@ the8472 @nikomatsakis , @ Dark-Legion : ๊ธ์ •์  ์ธ ํ”ผ๋“œ๋ฐฑ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค! ๋‚˜๋Š” ์ถ”์  ๋ฌธ์ œ์— ๋Œ€ํ•ด ๋„ˆ๋ฌด ์‹œ๋„๋Ÿฝ๊ณ  ์‹ถ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— IRLO ์Šค๋ ˆ๋“œ ์˜ ์ผ๋ถ€ ๋ฐœ์–ธ์— ๋Œ€๋‹ตํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•ฉ๋‹ˆ๋‹ค (์ „๋ฌธํ™”์— ๋Œ€ํ•œ ๋‰ด์Šค๋ฅผ ๊ธฐ๋Œ€ํ•˜๊ณ  ๋ฐฉ๊ธˆ ๋‚ด ์—‰๋ง์ง„์ฐฝ์„ ์ฐพ์€ ์—ฌ๋Ÿฌ๋ถ„ ๋ชจ๋‘์—๊ฒŒ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค : flushed :).

๊ฒŒ์‹œ ๊ฐ€๋Šฅํ•œ ๋‚ด์šฉ์„ ์ž‘์„ฑํ•˜๋ฉด ๋ณ„๋„์˜ RFC๋ฅผ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•œํŽธ, ์ €๋Š” ๋งํฌ ๋œ IRLO ์Šค๋ ˆ๋“œ ์— ๋Œ€ํ•œ ํ”ผ๋“œ๋ฐฑ์— ๋งค์šฐ ๊ฐœ๋ฐฉ์ ์ž…๋‹ˆ๋‹ค. aturon์˜ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์—์„œ ๋” ๊ธด ์˜ˆ์ œ๋ฅผ ์ถ”๊ฐ€ ํ–ˆ์œผ๋ฏ€๋กœ ์ž์œ ๋กญ๊ฒŒ ์˜๊ฒฌ์„ ๋งํ•˜์‹ญ์‹œ์˜ค!

๋‚˜๋Š” ๋˜ํ•œ impls ์ „๋ฌธํ™”์— ๋Œ€ํ•œ ์ผ์ข…์˜ ๋งˆ์ปค๋ฅผ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

2021 ๋…„ ์—๋””์…˜ ์ ‘๊ทผ ๋ฐฉ์‹์„ ํ†ตํ•ด ์ถ”๊ฐ€ ํ‚ค์›Œ๋“œ (์˜ˆ specialize )๋ฅผ ์˜ˆ์•ฝ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์˜ ๋ณต์žก์„ฑ๊ณผ ์—ญ์‚ฌ๋ฅผ ์‚ดํŽด๋ณด๋ฉด 2021 ์—๋””์…˜์ด ์ถœ์‹œ๋˜๊ธฐ ์ „์— ์•ˆ์ •ํ™”๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค (์ œ ์ƒ๊ฐ์— ํ‹€๋ฆฐ ๊ฒƒ์„ ์ฆ๋ช…ํ•  ์ˆ˜ ์žˆ์Œ). )์ด ํ•ฉ๋ฆฌ์ ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋งˆ์ปค๋กœ ์ ํ•ฉํ•œ ๊ฒƒ์œผ๋กœ ๋ณด์ด๋Š” ์œ ์ผํ•œ ๊ธฐ์กด ํ‚ค์›Œ๋“œ ๋Š” super ?

https://github.com/rust-lang/rust/issues/31844#issuecomment -639977601์—์„œ @LLFourn ์˜ ์˜ˆ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜์—ฌ ์š”์•ฝ :

  • 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 ( specialize ์•ฝ์ž, impl ๋Š” implement ) ( @ssokolow ๊ฐ€ 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 ( specialize ์•ฝ์–ด impl ๋Š” implement )

"spec"์€ "specification"(์˜ˆ : "The HTML 5 spec")์˜ ์•ฝ์–ด๋กœ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์ด๋ฏธ ๋” ์นœ์ˆ™ํ•˜๊ธฐ ๋•Œ๋ฌธ์— "specialize"์— ๋Œ€ํ•œ ์ข‹์€ ์†๊ธฐ๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

override ๋Š” ์˜ˆ์•ฝ ๋œ ํ‚ค์›Œ๋“œ์ด๋ฉฐ, ํ•จ์ˆ˜์šฉ์œผ๋กœ ์˜๋„ ๋œ ๊ฒƒ์œผ๋กœ ๊ฐ€์ •ํ•˜๋ฏ€๋กœ impl ๋ธ”๋ก์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

specialize ๋˜ํ•œ ๋กœ์ผ€์ผ์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์˜ค์ŠคํŠธ๋ ˆ์ผ๋ฆฌ์•„ ์ธ์€ ์ €์—๊ฒŒ ํŠนํ™”๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ 'spec'์„ ์‚ฌ์šฉํ•˜๋ฉด ๋กœ์ผ€์ผ ๋ชจํ˜ธ์„ฑ์ด ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

specialize ๋˜ํ•œ ๋กœ์ผ€์ผ์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์˜ค์ŠคํŠธ๋ ˆ์ผ๋ฆฌ์•„ ์ธ์€ ์ €์—๊ฒŒ ํŠนํ™”๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ 'spec'์„ ์‚ฌ์šฉํ•˜๋ฉด ๋กœ์ผ€์ผ ๋ชจํ˜ธ์„ฑ์ด ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

'spec'์ด ์‚ฌ์–‘์˜ ์ผ๋ฐ˜์ ์ธ ์•ฝ์–ด๋ผ๋Š” ์ ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ์ž‘๋™ํ•˜๋ฏ€๋กœ 'spec'์„ ์‚ฌ์šฉํ•˜์—ฌ ์ „๋ฌธํ™”๋ฅผ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์ด ํ˜ผ๋ž€ ์Šค๋Ÿฌ์šธ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํ˜ธ์ฃผ์—์„œ ์ฒ ์ž๊ฐ€ ๋‹ค๋ฅธ ๊ฒฝ์šฐ์—๋„ 'z'๋˜๋Š” 's'๋กœ ์ฒ ์ž๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ๋ชจ๋“  ์‚ฌ๋žŒ์ด ์˜๋„ ํ•œ ๋‹จ์–ด๋ฅผ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์บ๋‚˜๋‹ค์ธ์œผ๋กœ์„œ ์ €๋Š” ์ „๋ฌธํ™” / ์ „๋ฌธํ™”๊ฐ€ ๋กœ์ผ€์ผ์— ๋”ฐ๋ผ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ์‚ฌ์šฉ๋˜๋Š” ์œ ์ผํ•œ ๋‹จ์–ด๊ฐ€ ์•„๋‹ˆ๋ผ๊ณ  ๋งํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ๋Š” "์ƒ‰์ƒ"์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด ๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ "์ƒ‰์ƒ"๋Œ€์‹  ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๋“œ๋ฌผ์ง€๋งŒ ํ•ญ์ƒ ๋‚˜๋ฅผ ๊ดด๋กญ ํž™๋‹ˆ๋‹ค. ์ข‹๋“  ๋‚˜์˜ ๋“  ๋ฏธ๊ตญ ์˜์–ด๋Š” API ๋””์ž์ธ์—์„œ ์‚ฌ์‹ค์ƒ์˜ ํ‘œ์ค€์ด๋ฉฐ ์ƒ‰์ƒ / ์ƒ‰์ƒ๊ณผ ๊ฐ™์€ ๋‹จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•œ ์ฒ ์ž๋ฅผ ๋‹ค๋ฅธ ์ฒ ์ž๋ณด๋‹ค ์„ ํ˜ธํ•˜๋Š” ๊ฒƒ์„ ์„ ํƒํ•˜๋Š” ๊ฒƒ์€ ์‹ค์ œ๋กœ ์ธ์œ„์ ์œผ๋กœ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ํ”ผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

"spec"์ด "specification"์„ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ๊ฐ•๋ ฅํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š”์ง€ ๊ฐ์•ˆํ•  ๋•Œ, ์ด๊ฒƒ์ด ๋ฏธ๊ตญ์‹ ์˜์–ด ์ฒ ์ž๋ฅผ ๊ฐ€์žฅ ์ตœ์•…์˜ ์˜ต์…˜์œผ๋กœ ๊ฐ„์ฃผํ•ด์•ผํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ์ƒํ™ฉ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์‹ค ์ผ ์ˆ˜๋„ ์žˆ์ง€๋งŒ ๊ทธ๋ ‡๋‹ค๊ณ ํ•ด์„œ ์‚ฌ์šฉํ•ด๋„๋œ๋‹ค๋Š” ์˜๋ฏธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด "์ƒ‰์ƒ์„ ์ƒ‰์ƒ์œผ๋กœ ์‚ฌ์šฉ"๊ณผ ๊ฐ™์€ ์ˆ˜์ž…์„ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ํ•ญ์ƒ s ๋Œ€ z๋กœ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค. ํฌ์šฉ์„ฑ๊ณผ ์ ‘๊ทผ์„ฑ์— ๋Œ€ํ•œ Rust์˜ ๊ธ์ •์  ์ธ ํƒœ๋„๋ฅผ ๊ฐ์•ˆํ•  ๋•Œ, ์ƒ‰์ƒ / ์ƒ‰์ƒ ๋ฐ s / z์™€ ๊ฐ™์€ ์ž‘์€ ์‚ฌ์šฉ์ž ๋ถˆ๋งŒ์ด ์Œ“์ด๊ธฐ ๋•Œ๋ฌธ์— ๋กœ์ผ€์ผ์— ์˜์กดํ•˜์ง€ ์•Š๋Š” ์–ธ์–ด ์šฉ์–ด๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์›์น™์ ์œผ๋กœ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๋งŽ์€ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค์ง€ ์•Š๋Š” ๋กœ์ผ€์ผ ์ค‘๋ฆฝ์  ์ธ ์„ ํƒ์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์€ ํšŒ์˜์ ์ž…๋‹ˆ๋‹ค.

๋น„์˜์–ด๊ถŒ ์›์–ด๋ฏผ์œผ๋กœ์„œ ์ €๋Š” ์›์–ด๋ฏผ์ด ํฌ์šฉ์„ฑ์— ๋Œ€ํ•œ ์žฅ๋ฒฝ์œผ๋กœ ์ถ”๊ฐ€ u ์— ๋Œ€ํ•ด ๋ถˆํ‰ํ•˜๋Š” ๊ฒƒ์ด ๋‹ค์†Œ ์žฌ๋ฏธ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์ฒ ์ž๊ฐ€ ์กฐ๊ธˆ ์ด์ƒํ•˜์ง€ ์•Š๊ณ  ์™„์ „ํžˆ ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ์ž‘์„ฑ ๋˜์—ˆ๋‹ค๋ฉด ์–ด๋–จ์ง€ ์ƒ์ƒํ•ด๋ณด์‹ญ์‹œ์˜ค.

๋‹ค๋ฅด๊ฒŒ ๋งํ•˜๋ฉด Rust์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ชจ๋“  ์šฉ์–ด๋Š” ๋กœ์ผ€์ผ์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

์ข‹๋“  ๋‚˜์˜ ๋“  Rust์˜ ๊ฒƒ๋“ค์€ ๋ฏธ๊ตญ ์˜์–ด๋กœ ์ฒ ์ž๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์žˆ๋Š” ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์ด๊ฒƒ์€ ์ œ 2 ๋˜๋Š” ์ œ 3 ์–ธ์–ด๋กœ ์ž‘์—…ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ๋Š” ์ฒ ์ž๋ฅผ ์•ฝ๊ฐ„ ์กฐ์ •ํ•ด์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ฐ”๋กœ ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ํ•จ๊ป˜ ์ผํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐ ํ•„์š”ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์™€ - ๋‚˜๋Š” ์˜์–ด์˜ ์—ฌ๋Ÿฌ ๋ณ€์ข…์— ๊ฑธ์ณ ๊ฐ™์€ ์ฒ ์ž๊ฐ€ ๋‹จ์–ด๋ฅผ ์„ ํƒํ•˜๋Š” ๋…ธ๋ ฅ์˜ ํ˜œํƒ์ด ์ข‹์€์—๊ฒŒ ๋ช…ํ™•ํ•œ ์šฉ์–ด๋ฅผ ๋”ฐ๊ธฐ์— ํ•œ๊ณ„ ๋น„๊ต ์ƒ๊ฐ spec ์œ„์˜ ์ง€์  ๋ชจํ˜ธํ•ฉ๋‹ˆ๋‹ค.

special ๋ฅผ ํ‚ค์›Œ๋“œ๋กœ ์‚ฌ์šฉ ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

๋˜๋Š” specialize ๋ฐ specialise ๋‘ ๊ฐœ์˜ ํ‚ค์›Œ๋“œ๋ฅผ ๋งŒ๋“ค๊ณ  ๋™๋“ฑํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค ...

(์•„๋‹ˆ๋ฉด ์žฌ๋ฐŒ๋Š” ๋ฏธ๊ตญ์ธ์ด ์•„๋‹Œ ์‚ฌ๋žŒ๋“ค์€ ์ง„์งœ ์˜ฌ๋ฐ”๋ฅธ ์ฒ ์ž๋ฅผ ๋ฐฐ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค : us : ๐Ÿ˜‚)

๋‚˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์–ธ์–ด๊ฐ€ํ•˜๋Š” ์ผ์— ๋Œ€ํ•ด ๋งํ•  ์ˆ˜ ์—†์ง€๋งŒ CSS๋Š” ์ƒˆ๋กœ์šด ๋ชจ๋“  ๊ฒƒ์— ๋ฏธ๊ตญ ์˜์–ด ์ฒ ์ž๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ผํ™” ์ ์œผ๋กœ ๋ฏธ๊ตญ ์˜์–ด๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ๋„ ๋” ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@ mark-im ๋ถˆํ–‰ํ•˜๊ฒŒ๋„, ๊ทธ๊ฒƒ์€ Rust๊ฐ€ ํ•™์Šต์ž๊ฐ€ ๋‚˜์˜ฌ ์ˆ˜์žˆ๋Š” ๋ชจ๋“  ์ฃผ์š” ์–ธ์–ด๋กœ ๋Œ€์ฒด ํ‚ค์›Œ๋“œ ์„ธํŠธ๋ฅผ ๊ฐ€์ ธ์•ผํ•œ๋‹ค๋Š” ์ฃผ์žฅ์œผ๋กœ ์ด์–ด์ง€๋Š” ๋ฏธ๋„๋Ÿฌ์šด ๊ฒฝ์‚ฌ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ์‚ฌ๋žŒ๊ณผ ํŒŒ์„œ๋Š” ๊ณต๋ฐฑ ์ด ๊ทธ๋ ‡๊ฒŒ ๋‹ค์–‘ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ƒ๊ฐ์—๋งŒ ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ํ‚ค์›Œ๋“œ์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ ๋™์˜์–ด๋ฅผ ๊ฐ–๋„๋ก ์–ธ์–ด๋ฅผ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

(๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๋™๋“ฑํ•œ ๋™์˜์–ด์— ๋Œ€ํ•œ ํ‘ธ์‹œ๋ฅผ ์ž ์žฌ์ ์œผ๋กœ ๊ฑด ๋“œ๋ฆฌ๋Š” ๊ฒƒ์€ ๋งํ•  ๊ฒƒ๋„์—†๊ณ , ๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ทธ๊ฒƒ๋“ค์ด ๋„ท ๋„ค๊ฑฐํ‹ฐ๋ธŒ๊ฐ€๋˜์ง€ ์•Š๋„๋กํ•˜๊ธฐ ์œ„ํ•ด rustdoc ๋””์ž์ธ๊ณผ ๊ตฌํ˜„ ์ž‘์—…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.)

์ด ์‹๋ณ„์ž๊ฐ€ ์–ด๋–ค ์˜์–ด ๋ฐฉ์–ธ์„ ์‚ฌ์šฉํ•˜๊ธธ ์›ํ•˜๋Š”์ง€ ๋…ผ์Ÿํ•˜๋Š” ๋Œ€์‹  ํƒ€ํ˜‘ํ•˜์—ฌ ํžˆ๋ธŒ๋ฆฌ์–ด๋กœ ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@ssokolow ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฏธ๋„๋Ÿฌ์šด ์Šฌ๋กœํ”„ ์ธ์ˆ˜๋Š” ์‚ฌ์šฉํ•˜๊ธฐ์— ๊ฐ•๋ ฅํ•œ ์ธ์ˆ˜๊ฐ€ ์•„๋‹ˆ์ง€๋งŒ์ด ๊ฒฝ์šฐ์—๋Š” ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ์–ธ์–ด๊ฐ€ ๊ดœ์ฐฎ๋‹ค๊ณ  ์ฃผ์žฅ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ทธ๋ ‡์ง€ ์•Š์€ ๋ฐ๋Š” ์ ์–ด๋„ ๋‘ ๊ฐ€์ง€ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ๋œ ์ผ๋ถ€ ๋‹จ์–ด๋Š” ๋™์ผ ํ•ด ๋ณด์ด์ง€๋งŒ ์˜๋ฏธ๊ฐ€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค (์ง€๊ธˆ์€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ด€๋ จ ์˜ˆ์ œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์ง€๋งŒ ์ž„์˜์˜ ์˜ˆ์ œ : ์Šฌ๋กœ๋ฐ”ํ‚ค์•„์–ด๋กœ and a and ๋Š” ์˜์–ด๋กœ
  • ์‚ฌ๋žŒ๋“ค ์€ ์–ธ์–ด ๋ฅผ ์•Œ๊ณ  ์žˆ๋”๋ผ๋„ ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ๋œ ์ฝ”๋“œ๋ฅผ ์ฝ๋Š” ๋ฐ ํฐ ์–ด๋ ค์›€์„ ๊ฒช์„ ๊ฒƒ ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ฒฝํ—˜์œผ๋กœ ์•Œ๊ณ ์žˆ๋‹ค. (๊ธด ์ด์•ผ๊ธฐ ์งง๊ฒŒ : ๋‚˜๋Š” ๋Œ€ํ•™ ๊ต์œก ์‚ฌ๊ธฐ์—์„œ ์˜์–ด์—์„œ "๋ชจ๊ตญ์–ด"๋กœ ์ง์ ‘ ๋ฒˆ์—ญ ๋œ ์šฉ์–ด๊ฐ€์žˆ๋Š” ์ผ๋ถ€ ํ…์ŠคํŠธ๋ฅผ ์ดํ•ดํ•˜๋Š” ๋ฐ ํฐ ์–ด๋ ค์›€์„ ๊ฒช์—ˆ์Šต๋‹ˆ๋‹ค.)

์ด์ œ ๊ฑฐ๊พธ๋กœ ์ž‘์—…ํ•˜๋ฉด ์™œ ๋‹ค๋ฅธ ์–ธ์–ด๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ์˜์–ด ๋ฐฉ์–ธ์„ ์„ ํ˜ธํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ? ๋‚˜๋Š” ์š”์ ์ด ๋ณด์ด์ง€ ์•Š๋Š”๋‹ค. ์ผ๊ด€์„ฑ (๋ชจ๋“  ๊ฒƒ์ด ๋ฏธ๊ตญ ์˜์–ด ์ž„)์€ ๊ฐ€์žฅ ๊ฐ„๋‹จํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šฐ ๋ฉฐ ์˜ค๋ฅ˜ ๋ฐœ์ƒ ๊ฐ€๋Šฅ์„ฑ์ด ๊ฐ€์žฅ ๋‚ฎ์Šต๋‹ˆ๋‹ค.

์ด ๋ชจ๋“  ๋ง์€ "XXX๋ฅผ ์˜๋ฏธ ํ–ˆ์Šต๋‹ˆ๊นŒ?"์— ๋งค์šฐ ๋งŒ์กฑํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ์ ‘๊ทผ ๋ฐฉ์‹. ๋‹ค๋ฅธ ๋ฌธ์ œ๊ฐ€์—†๋Š” ์ค‘๋ฆฝ์  ์ธ ๋‹จ์–ด๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

์ ์–ด๋„ ์•„๋ฌด๋„ ์ถ•๊ตฌ๋ฅผ ์ฝ”๋“œ๋กœ ๋…ผ์˜ ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ;)

์˜์–ด ์›์–ด๋ฏผ์˜ ์•ฝ 70 % ๊ฐ€ ๋ฏธ๊ตญ ์ฒ ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ตญ๊ฐ€์— ์‚ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ..

"-ize ์ฒ ์ž๋Š” ์ข…์ข… ์˜๊ตญ์—์„œ ๋ฏธ๊ตญ์ฃผ์˜๋กœ ์ž˜๋ชป ์ธ์‹๋ฉ๋‹ˆ๋‹ค. 15 ์„ธ๊ธฐ๋ถ€ํ„ฐ ์‚ฌ์šฉ๋˜์–ด -ise๋ณด๋‹ค ํ•œ ์„ธ๊ธฐ๊ฐ€ ๋„˜๊ฒŒ ์ด์ „์— ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. -ize๋Š” ๊ทธ๋ฆฌ์Šค์–ด -ฮนฮถฮตฮนฮฝ -izein ๋ฐ Latin -izฤre์—์„œ ์ง์ ‘ ์˜จ ๋ฐ˜๋ฉด- ise๋Š” French -iser๋ฅผ ํ†ตํ•ด ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. OED (Oxford English Dictionary)๋Š” -ize๋ฅผ ๊ถŒ์žฅํ•˜๊ณ  -ise ํ˜•์‹์„ ๋Œ€์•ˆ์œผ๋กœ ๋‚˜์—ดํ•ฉ๋‹ˆ๋‹ค. "

"Henry Watson Fowler์˜ A Dictionary of Modern English Usage, Hart 's Rules ๋ฐ The Oxford Guide to English Usage์™€ ๊ฐ™์€ Oxford University Press (OUP)์˜ ๊ฐ„ํ–‰๋ฌผ๋„ -ize๋ฅผ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Robert Allan์˜ Pocket Fowler์˜ Modern English Usage๋Š” ๋‘ ๊ฐ€์ง€ ์ฒ ์ž๋ฅผ ๊ณ ๋ คํ•ฉ๋‹ˆ๋‹ค. ๋ฏธ๊ตญ์„ ์ œ์™ธํ•œ ๋ชจ๋“  ์ง€์—ญ์—์„œ ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค. "

์‹ฌํŒ. https://en.wikipedia.org/wiki/American_and_British_English_spelling_differences# -ise, _- ize _ (-isation, _- ization)

์ŠคํŽ˜์ธ์–ด์™€ ์ดํƒˆ๋ฆฌ์•„์–ด์—๋Š” az ๋˜๋Š” 2๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ํ”„๋ž‘์Šค์–ด๊ฐ€ ์–ด๋””์—์„œ -iser๋ฅผ ์–ป๋Š” ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

ํŠน์ • ํ‚ค์›Œ๋“œ์™€ ์ด๋ฆ„์„ ๋‘˜๋Ÿฌ์‹ผ ์ž์ „๊ฑฐ ์‰๋”ฉ์„ ๋‚ด๋ถ€ ์Šค๋ ˆ๋“œ ๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ด ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ง„ํ–‰ ์ƒํ™ฉ ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•ด์ด ๋ฌธ์ œ๋ฅผ ๋”ฐ๋ฅด๊ณ  ์žˆ์œผ๋ฉฐ์ด ํ† ๋ก ์€ ์•ฝ๊ฐ„ ์‹œ๋„๋Ÿฌ์›Œ์ง€๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰