Rust 㧠Generic ãªæ°å¤åãä½ã
ã¡ã¾ãã§è©±é¡(ï¼) ã® Rust è¨èªãæ¨å¹´æ«ããããããæ¥æ¬èªæ
å ±ãå
¨ç¶ç¡ããå
é§è
ã«ãªããã£ã³ã¹ï¼ãã¨ãæããªããã®ãã®ããã¦ãããå
æ¥ã®0.1ççºè¡¨ã§ä¸æ°ã«ç¥å度ãä¸ãã£ã¦ãã¾ã(´ã»Ïã»`)ã¨ãã¦ããgifnksmã§ãã
0.1ãªãªã¼ã¹ã§ããããå¤ããã¾ããããtag ã enum ã«ãªã£ãããalt ã§åæåã®å¤ã§åå²ããã¨ãã«æ«å°¾ã«ã©ã£ã¨(.) ãã¤ããªãã¦ããããªã£ãããå®è£
ããäºå®ã®æ©è½(Proposals · graydon/rust Wiki · GitHub) ãã¾ã ã¾ã ãããããããä»å¾ã«ã¾ãã¾ãæå¾
ã§ãã
ãã¦ãã¦ããããªRustè¨èªã§ã Generic ãªæ´æ°åãä½ã£ã¦ã¿ã¾ããã
ãªãä½ã£ããã¨è¨ãã¾ãã¨ã以ä¸ã®ãããªã³ã¼ããæ®éã«ã³ã³ãã¤ã«ããå ´åã
fn add<T>(a: T, b: T) -> T { a + b }
以ä¸ã®ãããªã¨ã©ã¼ã§ã³ã³ãã¤ã«ãéããªããªã£ã¦ãã¾ãããã§ãã
main.rs:17:29: 17:34 error: binary operation + cannot be applied to type `'a` main.rs:17 fn add<T>(a: T, b: T) -> T { a + b }
Tåã«ã¯ +
æ¼ç®åãå®ç¾©ããã¦ãã¼ãï¼ã¨ããã¨ã©ã¼ã§ããC++ãDã®Templateã¨ã¯éããRust 㯠Generics ã«ãã£ã¦ããªã¢ã¼ãã£ãºã ãå®ç¾ãã¦ãã¾ãã®ã§ãGeneric é¢æ°ãå¼ã³åºããæç¹ã§ã¯ç¡ããæ¸ããæç¹ã§é¢æ°æ¬ä½ãã³ã³ãã¤ã«ãããã³ã³ãã¤ã«ã¨ã©ã¼ã«ãªã£ã¦ããããã§ãã
ã§ã¯ãã©ãããããGenericãªæ°å¤ã表ãã¤ã³ã¿ã¼ãã§ã¼ã¹ãæ¸ãã¦ãã£ã¦ããã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ã«å¯¾ããåæ°å¤åã®å®è£
ãæ¸ãã¦ããã°ããããã§ããé¢æ°ãå¼ã³åºãå´ã§ã¯T
ã§ã¯ãªãGenericãªæ°å¤åãæå®ãã¦ããã¾ããå
·ä½çã«ã¯ã以ä¸ã®éãã
use std; import std::io; // Generic ãªæ°å¤åã®å®ç¾© iface num<T> { fn val() -> T; fn zero() -> num<T>; fn add(++num<T>) -> num<T>; fn sub(++num<T>) -> num<T>; } // å®è£ (uint) impl of num<uint> for uint { fn val() -> uint { self } fn zero() -> num<uint> { 0u as (num<uint>) } fn add(a: num<uint>) -> num<uint> { (self + a.val()) as (num<uint>) } fn sub(a: num<uint>) -> num<uint> { (self - a.val()) as (num<uint>) } } // å®è£ (int) impl of num<int> for int { fn val() -> int { self } fn zero() -> num<int> { 0 as (num<int>) } fn add(a: num<int>) -> num<int> { (self + a.val()) as (num<int>) } fn sub(a: num<int>) -> num<int> { (self - a.val()) as (num<int>) } } // Generic ãªæ°å¤åã使ã£ãé¢æ° (è¦ç´ æ°ã0ã®æã¯æ»ã¬) fn sum<T>(vals: [num<T>]) -> num<T> { vec::foldl(vals[0].zero(), vals) { |s, t| s.add(t) } } fn main() { // [int] ã®åãæ±ãã std::io::println(#fmt("%d", sum(vec::map([1, 2, 3]) { |v| v as (num<int>) }).val())); // [uint] ã®åãæ±ãã std::io::println(#fmt("%u", sum(vec::map([1u, 2u, 3u]) { |v| v as (num<uint>) }).val())); }
add
ã§å¼æ°ã«ã¨ãæ°å¤åãèªåã¨åãåã§ãããã¨ãä¿è¨¼ããããã«ãT
ãåãã©ã¡ã¼ã¿ã¨ãã¦num
ã«è¿½å ãã¦ãã¾ããã¾ããnum<T>
åã®"0"ãåå¾ããæ¹æ³ãããããªãã£ãã®ã§ãé
åã®0çªç®ã®è¦ç´ ã«å¯¾ãã¦.zero()
ãå¼ã³åºãã¨ããæ ¼å¥½æªãå®è£
ã«ãªã£ã¦ãã¾ã(ããã¯ãifaceãå®æ°ãæã¦ãããã«ãªãã°è§£æ±ºãããããï¼)
ä¸è¨ã®ããã«ãèªåã§å®è£
ãããä¸æ ¼å¥½ã«ãªãã¾ãããLanguage Proposal ã®Proposals for interfacesã®Operator overloadingã®ç¯ã«ããã°ã
iface num { fn +(self, self) -> self; fn -(self, self) -> self; /* etc */ }
ã®ãããªnumãçµã¿è¾¼ã¿åã«å¯¾ãã¦å®ç¾©ãããããã«ãªããããã®ã§ãã¦ã¼ã¶ã¼å´ã§ããããä¸æ ¼å¥½ãªå®ç¾©ãããªãã¦ããããªãããããã¾ããã
ããããã¦ã¼ã¶ã¼ãå¾ä»ãã§åã«å¯¾ããæä½ã追å ã§ããããéãããã¹ã³ã¼ãã§ãªã¼ãã³ã¯ã©ã¹çã«æä½ã追å ã§ããããããHaskellã®åã¯ã©ã¹ãæãåºããã¾ããå¾çºè¨èªãªã ããã£ã¦ãã¤ã³ã¿ã¼ãã§ã¼ã¹ã®ä»æ§ãæ´ç·´ããã¦ã¦è¯ãæãã ãªã¼ãã¨æãã¾ãã
ã·ã¹ãã ããã°ã©ãã³ã°è¨èªãRustã®ä»å¾ã«æå¾
ã§ããï¼ï¼
2012/9/27 追è¨
æè¿ã® Rust ã§ã¯ãã³ã¢ã©ã¤ãã©ãªã«Num
ãã¬ã¤ããæ¨æºã§çµã¿è¾¼ã¾ãã¦ãã¾ã (以ä¸ã¯ã2012/9/27 æç¹ã§ã® incoming ãã©ã³ãããæã£ã¦ããå®ç¾©ã§ã)
trait Num { // FIXME: Trait composition. (#2616) pure fn add(other: &self) -> self; pure fn sub(other: &self) -> self; pure fn mul(other: &self) -> self; pure fn div(other: &self) -> self; pure fn modulo(other: &self) -> self; pure fn neg() -> self; pure fn to_int() -> int; static pure fn from_int(n: int) -> self; }
ãããªæãå®è£ ï¼ä½¿ç¨ã§ãã¾ãã
// bigint::add ãªã©ã¯å¥éå®ç¾©ãã¦ãã impl BigInt : Num { pure fn add(other: &BigInt) -> BigInt { bigint::add(&self, other) } pure fn sub(other: &BigInt) -> BigInt { bigint::sub(&self, other) } ... static pure fn from_int(n: int) -> BigInt { bigint::from_int(n) } } fn factorial(n: uint) { let mut prod: BigInt = from_int(1); for uint::range(2, n + 1) |i| { prod *= from_int(i); // 左辺㮠prod ããåæ¨è«å¯è½ } }
Num
ãã¬ã¤ããå®è£
ããåã«ã¤ãã¦ã¯ãæ¼ç®åããªã¼ãã¼ãã¼ãããããã®ã使ããã¾ããRustã®æ¼ç®åãªã¼ãã¼ãã¼ã㯠core::ops
ã® Add
ãã¬ã¤ããªã©ãåæ¼ç®åæ¯ã«å®ç¾©ããããªã¼ãã¼ãã¼ãç¨ãã¬ã¤ããå®è£
ããã®ãæ¬æ¥ã®ããæ¹ã§ãããã©ãããNum
ãã¬ã¤ãã¯ç¹å¥æ±ãããã¦ããããã§ãã
fn main() { let n: BigInt = from_int(1); let m = n + from_int(2); let k = n * m - from_int(10); }