Rustコンパイラはwhere
句で異なる動作をしているようです。 where
句と特性が型として使用されていて、where句の境界として使用されていないときのエラー
mod sub {
use std::mem;
static mut FF : *const Foo = &NopFoo;
pub trait Foo: Send + Sync {
fn foo(&self);
}
pub struct NopFoo;
impl Foo for NopFoo {
fn foo(&self) { println!("Nop"); }
}
pub struct HelloFoo {
pub num: i64,
}
impl Foo for HelloFoo {
fn foo(&self) { println!("Hello, {}", self.num); }
}
pub fn set_ff<M>(make_foo: M) -> bool
where M: FnOnce() -> Box<Foo> // <== Here
{
unsafe {
FF = mem::transmute(make_foo());
}
false
}
pub fn get_ff() -> Option<&'static Foo> {
Some(unsafe { &*FF })
}
}
fn main() {
sub::get_ff().unwrap().foo();
let f = sub::HelloFoo{num: 42};
sub::set_ff(|| Box::new(f));
sub::get_ff().unwrap().foo();
}
、それは罰金、版画作品:私はsub::set_foo()
からwhere
句を削除した場合
Nop
Hello, 42
錆コンパイラがエラーを報告します[ E0277]および[E0308]
mod sub {
use std::mem;
static mut FF : *const Foo = &NopFoo;
pub trait Foo: Send + Sync {
fn foo(&self);
}
pub struct NopFoo;
impl Foo for NopFoo {
fn foo(&self) { println!("Nop"); }
}
pub struct HelloFoo {
pub num: i64,
}
impl Foo for HelloFoo {
fn foo(&self) { println!("Hello, {}", self.num); }
}
pub fn set_ff(make_foo: Box<Foo>) -> bool // <== Here
{
unsafe {
FF = mem::transmute(make_foo());
}
false
}
pub fn get_ff() -> Option<&'static Foo> {
Some(unsafe { &*FF })
}
}
fn main() {
sub::get_ff().unwrap().foo();
let f = sub::HelloFoo{num: 42};
sub::set_ff(|| Box::new(f));
sub::get_ff().unwrap().foo();
}
私はそれが正常に動作する必要がありますと思ったが、コンパイラが代わりにエラーを報告:
error: the trait bound `std::ops::FnOnce() -> Box<sub::Foo + 'static> + 'static: std::marker::Sized` is not satisfied [--explain E0277]
--> <anon>:24:19
24 |> pub fn set_ff(make_foo: FnOnce() -> Box<Foo>) -> bool
|> ^^^^^^^^
note: `std::ops::FnOnce() -> Box<sub::Foo + 'static> + 'static` does not have a constant size known at compile-time
note: all local variables must have a statically known size
error: mismatched types [--explain E0308]
--> <anon>:41:17
41 |> sub::set_ff(|| Box::new(f));
|> ^^^^^^^^^^^^^^ expected trait std::ops::FnOnce, found closure
note: expected type `std::ops::FnOnce() -> Box<sub::Foo + 'static> + 'static`
note: found type `[[email protected]<anon>:41:17: 41:31 f:_]`
はなぜ錆のコンパイラは、第1に'static
とSized
を必要としないし、なぜ最初の仕事?
私のOSや錆のバージョン:
➜ ~ uname -a
Linux laptop 4.2.0-35-generiC#40~14.04.1-Ubuntu SMP Fri Mar 18 16:37:35 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
➜ ~ rustc --version
rustc 1.10.0-nightly (9c6904ca1 2016-05-18)
私はこの質問が以前に答えられたことを知っていますが、私は前のケースを見つけることができません。発見されたときは重複して自由に閉じるようにしてください。 – Shepmaster
greateの回答ありがとうございます!それは本当にたくさんの助けになります! – NeilShen