Rustã®é¢æ°ãã¤ã³ã¿ã®è½ã¨ãç©´
æ¦è¦: Rustã®é¢æ°ãã¤ã³ã¿ã®è½ã¨ãç©´ã«ã¤ãã¦
ãã®1: é¢æ°ãã¤ã³ã¿ã¯ã¯ãã¼ã¸ã£ã¨ã¯ç°ãªã
ããã¯C/C++ã«æ
£ãã¦ãã人ã«ã¯å½ããåã§ãããé¢æ°ãã¤ã³ã¿å (fn()
) ã¨ã¯ãã¼ã¸ã£å (Fn()
) ã«ã¯é大ãªéããããã¾ããããã¯ãé¢æ°ãã¤ã³ã¿ã¯ç°å¢ããã£ããã£ã¼ããªãã¨ãããã¨ã§ãã大éæã«ããã¨ã
- é¢æ°ãã¤ã³ã¿ã¯ãããæ©æ¢°èªã³ã¼ãã®ã¢ãã¬ã¹
- ã¯ãã¼ã¸ã£ã¯ãé¢æ°ãã¤ã³ã¿ã¨ããã£ããã£ã¼ããç°å¢ã®å¯¾
ãªã®ã§ãé¢æ°ãã¤ã³ã¿ã¯ãã²ã¨ã¤ã®ããã°ã©ã ã«ã¤ãååã¨ãã¦æéåãããªãã®ã«å¯¾ããã¯ãã¼ã¸ã£ã¯ããã£ããã£ã¼ããç°å¢ã«ãã£ã¦ç¡éã«ããããã®ã¯ãã¼ã¸ã£ãä½ããã¨ãã§ãã¾ããä¾ãã°ã
fn main() { let closures = [3, 7, 1, 5, 8, 9, 2].iter().map(|&i| { move |j| i + j }).collect::<Vec<_>>(); println!("{}", closures[3](14)); }
ã¨ããã³ã¼ãã§ã¯ãã3ã足ãé¢æ°ãã7ã足ãé¢æ°ãã1ã足ãé¢æ°ãã5ã足ãé¢æ°ãâ¦â¦ ã®ããã«ããããã®ãé¢æ°ããåçã«çæãã¦ãã¾ãããããããã®ã¯ã¯ãã¼ã¸ã£ã§ãªãã¨ã§ãã¾ããã
é¢æ°ãã¤ã³ã¿ã¯åºæ¬çã«ã¯ fn
ã§å®ç¾©ããé¢æ°ããããä½ããã¨ãã§ãã¾ãããä¾å¤ã¨ãã¦ããã£ããã£ã¼ãã¦ããªãã¯ãã¼ã¸ã£ã¯é¢æ°ãã¤ã³ã¿ã¨ãã¦ä½¿ããã¨ãã§ãã¾ãã
fn main() { let f : fn(i32) -> i32 = |x| x + 1; println!("{}", f(3)); }
ãã®2: fn
ã¨æ¸ãããããèªä½ããã¤ã³ã¿å
Cè¨èªã§ã¯
int (*f)(void) = getchar;
ã®ããã«ãé¢æ°ãã¤ã³ã¿åã«ã¯æä½1åã® *
ãã¤ãã¾ããã対å¿ããRustã®è¨æ³ã§ã¯
let f : fn() -> i32 = i32::max_value;
ã®ããã«ã *
ã0åã§é¢æ°ãã¤ã³ã¿ã§ãããããã£ã¦ã
let f : *const fn() -> i32; // äºéãã¤ã³ã¿ï¼
ã¯ãé¢æ°ãã¤ã³ã¿ã¸ã®ãã¤ã³ã¿ã«ãªã£ã¦ãã¾ãã¾ãããããééããã¨FFIã§æªç¥ã®segfaultã«æ©ã¾ãããå¯è½æ§ãããã¾ãã
ãã®3: é¢æ°ã®åã¯é¢æ°ãã¤ã³ã¿åã§ã¯ãªã
ä¾ãã°ã以ä¸ã®ã³ã¼ãã¯ã³ã³ãã¤ã«ã¨ã©ã¼ã«ãªãã¾ãã
fn foo() { println!("foo"); } fn bar() { println!("bar"); } fn main() { let mut f = foo; if true { f = bar; } f(); }
Compiling playground v0.0.1 (file:///playground) error[E0308]: mismatched types --> src/main.rs:7:13 | 7 | f = bar; | ^^^ expected fn item, found a different fn item | = note: expected type `fn() {foo}` found type `fn() {bar}` error: aborting due to previous error error: Could not compile `playground`.
ããã§ã¯ fn()
ã§ã¯ãªãã fn() {foo}
ã fn() {bar}
ã¨ããåã表示ããã¦ãã¾ããããã¯é¢æ°å®ç¾©åã¨ãã°ããé¢æ°ãã¤ã³ã¿åã¨ã¯ç°ãªãã¾ãã
é¢æ°ãã¤ã³ã¿åã¨é¢æ°å®ç¾©åã®ããããããéãã¨ãã¦ãã¤ãæ°ãæãããã¾ãã以ä¸ã§ãããããã«ãé¢æ°å®ç¾©åã¯å®ã¯0ãã¤ãã§ãã
use std::mem; fn main() { println!("{}", mem::size_of_val(&main)); // 0 println!("{}", mem::size_of_val(&(main as fn()))); // 8 }
é¢æ°å®ç¾©åã¯ãé¢æ°ãã¨ã«ç°ãªãåãã¤ãã¦ããã®ã§ãããèªä½ã¯æ å ±ãæã£ã¦ããªãã¦ãå¼ã³åºããããã«ãªã£ã¦ãã¾ããC++ã§ããã°ãåé¢æ°ãã¨ã«ãã¡ã³ã¯ã¿ãªãã¸ã§ã¯ããä¸åå²ãå½ã¦ããã¦ããã以ä¸ã®ãããªç¶æ ã¨ã¿ããã¨ãã§ãã¾ãã
void foo_funptr() { printf("foo!\n"); } struct foo { int dummy; //C++ã«ã¯ZSTããªãã®ã§ // ç´æ¥å¼ã³åºã void operator()() const { printf("foo!\n"); } // é¢æ°ãã¤ã³ã¿ã¸ã®å¤æ void (*to_funptr())() const { return foo_funptr; } };
é¢æ°ãã¸ã§ããªã¯ã¹ãæã£ã¦ããå ´åã¯ãé¢æ°å®ç¾©åã«ã対å¿ããã¸ã§ããªã¯ã¹ãä¸ãããã¾ãããªããã³ã³ãã¤ã©ã¯ä¾¿å®ä¸ fn() {foo}
ã®ãããªè¡¨ç¤ºããã¾ãããé¢æ°å®ç¾©åãåæãã§æå®ãããã¨ã¯ã§ãã¾ãããããã¯ã¯ãã¼ã¸ã£å ([closure@src/main.rs:3:20: 3:25]
ãªã©ã¨è¡¨ç¤ºããã) ã¨åæ§ã§ãã
ãããã«ãããé常ã¯å¿ è¦ãªã¿ã¤ãã³ã°ã§é¢æ°ãã¤ã³ã¿åã«èªåã§å¤æãããã®ã§ãå¤ãªã³ã³ãã¤ã«ã¨ã©ã¼ãªã©ã«ééããªãéãæ°ã«ããå¿ è¦ã¯ãªãã§ãããã
ãã®4: é¢æ°ãã¤ã³ã¿åã«ã¯ABIã¨å®å ¨æ§ãã©ã°ãã¤ãããã
ç¹ã«ãC/C++ã¨ã®FFIãããã¨ãã¯ãABIãééããªãããã«æ³¨æãå¿
è¦ã§ããé常ã®Rusté¢æ°ã¯ extern "Rust" fn()
ãªã®ã«å¯¾ãã¦ãC/C++ã¨ç¸äºå¼ã³åºãããé¢æ°ã¯ extern "C" fn()
ã§ãããããã fn()
, extern fn()
ã¨çç¥ã§ãã¾ããã¾ã unsafe
ãã¤ã㦠unsafe fn()
ã®ããã«ãã§ãã¾ãã
ãªãã C++ã® extern "C"
ã¨ã¯ç°ãªããRustã® extern "C"
ã¯ABIãæå®ããã ãã§ããã³ã°ãªã³ã°è¦åãå¤æ´ãã¾ããããã³ã°ãªã³ã°ãç¡å¹åããã«ã¯å¥é #[no_mangle]
ãã¤ãã¾ãã
ã¾ããããã¾ãC++ã«æ £ãã¦ããã¨ãããã¥ããã§ããã
extern "C" fn foo() {} // ããã«å®ä½ããã
ã¨
extern "C" { fn foo(); // å¥ã®å ´æã«ããå®ä½ã¨ãªã³ã¯ãã }
ã¯æå³ãç°ãªãã¾ãã extern { .. }
ã¯ãå®ä½ãä»ã®å ´æã«ããã¨ãã«ä½¿ãã¾ãã