์ด๊ฒ์ ์ ๋ฌธํ์ ๋ํ ์ถ์ ๋ฌธ์ ์ ๋๋ค (rust-lang / rfcs # 1210).
์ฃผ์ ๊ตฌํ ๋จ๊ณ :
default impl
(https://github.com/rust-lang/rust/issues/37653)default
๋ฉค๋ฒ๊ฐ์๋ ๊ฒฝ์ฐ ๋น impls๋ฅผ ํ์ฉํด์ผํฉ๋๊น? https://github.com/rust-lang/rust/issues/48444RFC์ ํด๊ฒฐ๋์ง ์์ ์ง๋ฌธ :
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
๋ ๋๋ถ๋ถ์ ํจ์ ์ ํผํฉ๋๋ค .
๋ช ๊ฐ์ง ์ถ๊ฐ ๊ณต๊ฐ ์ง๋ฌธ :
์ ๋ฌธํ๊ฐ ๊ณ ์ ๊ท์น์ ๋ณ๊ฒฝํ๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
๊ทธ๋ณด๋ค ๋ ๋์ ๊ฒ์ "๋ฏธ๋ ํธํ์ฑ"๊ณ ์ ๊ท์น์ด ์์ ๊ฐ ์ ๋ฌธํ๋ฅผ ์๋นํ ๊ฐ๋ ฅํ ํต์ ํ์ ์ ์งํ๋ค๋ ๊ฒ์ ๋๋ค. ๊ทธ๊ฒ๋ค์ด ์์ผ๋ฉด default-impls๋ ๋ฉ์๋๋ฅผ ์ด์ด ๋๋ ๊ฒ์ด ํจ์ฌ ๋ ๋๋น ์ง๋๋ค.
๋๋ ๋ช ๋ฐฑํ ๋ถ์ ์ ์ธ ์ถ๋ก ์ ๊ฒฐ์ฝ ์ข์ํ์ง ์์์ต๋๋ค. ๋๋ ์ ์ฒด ๋ถ์ ์ ์ธ ์ถ๋ก ์ ๋ฌธํ๊ฐ ์ ๊ณตํ๋ ์ข์ ํํ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ด impl์ด ๊ตฌํ ๋ ์ ๋ฌธํ์ ํจ๊ป ํ์ฉ๋์ด์ผํฉ๋๊น? ์๋๋ฉด ๋ด๊ฐ ๋ญ๊ฐ๋ฅผ ๋์น๊ณ ์์ต๋๊น?
http://is.gd/3Ul0pe
์ด๊ฒ๊ณผ ๋์ผํ๊ฒ ์ปดํ์ผ ๋ ๊ฒ์ผ๋ก ์์ํ์ ๊ฒ์ ๋๋ค : http://is.gd/RyFIEl
๊ด๋ จ ์ ํ์ด ๊ด๋ จ๋์ด์์ ๋ ๊ฒน์นจ์ ๊ฒฐ์ ํ๋ ๋ฐ ๋ช ๊ฐ์ง ๋จ์ ์ด์๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ด๊ฒ์ ์ปดํ์ผ๋ฉ๋๋ค : http://is.gd/JBPzIX , ๋ฐ๋ฉด์ด ๋์ผํ ์ฝ๋๋ ๊ทธ๋ ์ง ์์ต๋๋ค : http://is.gd/0ksLPX
๋ค์์ ์ ๋ฌธํ๋ก ์ปดํ์ผ ํ ๊ฒ์ผ๋ก ์์๋๋ ์ฝ๋์ ๋๋ค.
#![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
๊ตฌํํ์ง ์์ผ๋ฏ๋ก ์ถฉ๋์ด ์์ด์ผํฉ๋๋ค.
ํ
์ฒ์ ๋ ๊ฐ์ง ์๋ฅผ ์ดํด๋ณผ ์๊ฐ์ด์์์ต๋๋ค. ์ฌ๊ธฐ ๋ด ๋ฉ๋ชจ๊ฐ ์์ต๋๋ค.
์ฒซ ๋ฒ์งธ ๊ฒฝ์ฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
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>
(T, U)
๊ฐ์ง ์ ์๊ธฐ ๋๋ฌธ์ ๋ ๊ฐ์ impl์ด ๊ฒน์นฉ๋๋ค.T: FromSqlRow<ST, DB>
U: FromSqlRow<SU, DB>
(T, U): FromSql<(ST, SU), DB>
์ด๊ฒ์ด ๊ฒฉ์ impls๊ฐ ํ์ฉํ๋ ์ํฉ์ ๋๋ค. ๊ฒน์น๋ ๊ฒฝ์ฐ์ ๋ํด ์ธ ๋ฒ์งธ impl์ ์์ฑํ๊ณ ์ด๋ป๊ฒํด์ผํ๋์ง ๋งํด์ผํฉ๋๋ค. ๋๋ ๋ถ์ ์ ์ธ ํน์ฑ impls๋ ๊ฒน์นจ์ ๋ฐฐ์ ํ๊ฑฐ๋ ๊ฐ๋ฅํ ์ผ์น๋ฅผ ์กฐ์ ํ ์์๋ ๋ฐฉ๋ฒ์ ์ ๊ณต ํ ์ ์์ต๋๋ค.
๋น์ ์ :
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/
- rust-lang / rfcs # 1023 https://github.com/rust-lang/rfcs/pull/1023
- rust-lang / rfcs # 1053 https://github.com/rust-lang/rfcs/issues/1053
- rust-lang / rfcs # 1148 https://github.com/rust-lang/rfcs/pull/1148
โ
๋น์ ์ด ์ธ๊ธ ๋์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ๋ฐ๊ณ ์์ต๋๋ค.
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ฑฐ๋ 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๊ฐ ์ด๋ฏธ ๊ฐ์กฐํ ๋ฌธ์ ์ ๊ด๋ จ์ด ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ด๊ฒ๋ค์ด ํ๋ฆด ์ ์๋์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ๊ฐ์ง๊ณ ์ถ๋ค:
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์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ฐ๋ฆฌ๋ ์์ ๊ธฐ๋ณธ ๋ธ๋ญํท 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์ ๋ํด ๊ฒฝ๊ณ ํ ์ ์์ต๋๋ค. ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ ๊ฐ์ฅ ์ ์๋ํฉ๋๋ค.
default
๋ฅผ ์ถ๊ฐํ์ฌ ๊ฒฝ๊ณ ๋ฅผ ๊ทน๋ณต ํ ์ ์์ต๋๋ค (๋๋ถ๋ถ์ ๊ฒฝ์ฐ).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์ ์ฌ์ฉํ์ฌ ์๋ฎฌ๋ ์ด์ ์ ์๋ํ๋ฉด ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค.
๋ฐ๋ณตํ๊ฒ ์ต๋๋ค. 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>>
๊ณ ๋ คํด ๋ณด๊ฒ ์ต๋๋ค. ๊ทธ๋
WithLabel<WithID<A>>
๋ฐ WithLabel<WithLabel<A>>
๋ค๋ฃน๋๋ค.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
์ (๋ฅผ) ์ด์ฉํ์ฌ ๊ฒน์น๋ ๋น ๋ง์ปค ํน์ฑ์ ํ์ฉ ํ ์ ์์ง๋ง์ด ํดํน์๋ ์ธ ๊ฐ์ง ํน์ฑ์ด ๋ ํ์ํฉ๋๋ค (ํ๋๋ ๋ง์ปค ํน์ฑ์ ๊ฑฐ์น๊ณ ๋ ๊ฐ๋ ์ ๋ฌธํ๋ฅผ ํตํด ์ง์์ง ๋ฐ์ดํฐ๋ฅผ ๋ค์ ํ๋ํ๊ธฐ์ํ ๊ฒ์
๋๋ค).
@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์ ํด์ํฉ๋๋ค"์
๋๋ค. ๋ฌธ์ ๋ ๋งค์ฐ ์ด์ํ ์ฝ๋๋ก ์ด์ด์ง๋ค๋ ๊ฒ์
๋๋ค.
์ฌ๊ธฐ์ ๋ ๋ฒ์งธ 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, ๊ทธ๋ค์ ์ด์จ๋ ๋ณํ๋ฅผ ๊นจ๊ณ ์์ต๋๋ค :
min_specialization
๊ฐํ๋ ์ผ).@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๋ฅผ ์ป๋ ์ง ํ์คํ์ง ์์ต๋๊น?
ํน์ ํค์๋์ ์ด๋ฆ์ ๋๋ฌ์ผ ์์ ๊ฑฐ ์๋ฉ์ ๋ด๋ถ ์ค๋ ๋ ๋ก ์ด๋ํ ์ ์์ต๋๊น? ์ด ๊ธฐ๋ฅ์ ๋ํ ์งํ ์ํฉ ์ ๋ฐ์ดํธ๋ฅผ ์ํด์ด ๋ฌธ์ ๋ฅผ ๋ฐ๋ฅด๊ณ ์์ผ๋ฉฐ์ด ํ ๋ก ์ ์ฝ๊ฐ ์๋๋ฌ์์ง๊ธฐ ์์ํ์ต๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๊ฐ๋ฐ์ค์ธ ์คํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์
#[min_specialization]
์ (๋ฅผ) ์ฌ์ฉํ๊ณ ์์๊ธฐ ๋๋ฌธ์ ๊ฒฝํ์ ๊ณต์ ํ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ์ต๋๋ค. ๋ชฉํ๋ ๊ฐ์ฅ ๊ฐ๋จํ ํํ๋ก ์ ๋ฌธํ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ๋ณด๋ค ๋ ๋น ๋ฅธ ๊ตฌํ์ผ๋ก ์ข์ ๊ฒฝ์ฐ๋ฅผ ๊ฐ๋ ๊ฒ์ ๋๋ค. ํนํ ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ ์ํธํ ์๊ณ ๋ฆฌ์ฆ์ ์ผ์ ํ ์๊ฐ์ ์คํํ์ง๋ง ๋ชจ๋ ์ ๋ ฅ์ดPublic
๋ก ํ์๋์ด ๋ ๋น ๋ฅธ ๊ฐ๋ณ ์๊ฐ์ผ๋ก ์คํ๋๋ ํน์ ๋ฒ์ ์ ๊ฐ๋๋กํ๋ ค๋ฉด (๊ณต๊ฐ ๋ ๊ฒฝ์ฐ์๋ ์คํ ์๊ฐ์ ํตํด ์ ๋ณด๋ฅผ ์ ์ถํ๋ ๋ฐ ์ ๊ฒฝ์ ์๋๋ค). ๋ํ ์ผ๋ถ ์๊ณ ๋ฆฌ์ฆ์ ํ์ ๊ณก์ ์ ์ด ์ ๊ทํ๋์๋์ง ์ฌ๋ถ์ ๋ฐ๋ผ ๋ ๋น ๋ฆ ๋๋ค. ์ด๊ฒ์ ์๋์ํค๊ธฐ ์ํด ์ฐ๋ฆฌ๋๊ทธ๋ฐ ๋ค์ ์ต๋ ์ต์ ์ ๋ฌธํ์ ์ค๋ช ๋๋๋ก _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์ ์์ ๋ฅผ ๋ด๊ฐ ์ผ๋์ ๋ ๊ฒ์ผ๋ก ๋ณํ :