小编Luk*_*odt的帖子

为什么`Index`特征的`Idx`类型参数可以被取消?

在Rust 1.14中,Index特征定义如下:

pub trait Index<Idx> where Idx: ?Sized {
    type Output: ?Sized;
    fn index(&self, index: Idx) -> &Self::Output;
}
Run Code Online (Sandbox Code Playgroud)

这里放宽SizedOutput类型的隐式绑定?Sized.这是有道理的,因为该index()方法返回一个引用Output.因此,可以使用未实现的类型,这是有用的; 例:

impl<T> Index<Range<usize>> for Vec<T> {
    type Output = [T];  // unsized!
    fn index(&self, index: Range<usize>) -> &[T] { … } // no problem: &[T] is sized!
}
Run Code Online (Sandbox Code Playgroud)

Idx类型参数的隐式绑定也轻松,可以无胶.但是Idx作为方法参数使用值,并且使用未定义类型作为参数是不可能的AFAIK.为什么Idx允许不合格?

language-lawyer rust

7
推荐指数
1
解决办法
201
查看次数

为什么这个Rust程序忽略了不变性

我有以下Rust程序,我希望它会导致编译错误,因为x稍后会重新分配.但它符合并提供输出.为什么?

fn main() {
   let (x, y) = (1, 3);
   println!("X is {} and Y is {}", x, y);

   let x: i32 = 565;
   println!("Now X is {}", x);
}
Run Code Online (Sandbox Code Playgroud)

rust

7
推荐指数
1
解决办法
233
查看次数

为什么指针算术是段错误的原因?

为什么这个指针算术(没有读取或写入这些指针后面的数据)是segfault的原因?

#![allow(dead_code,unused_variables)]
use std::cell::Cell;

struct Bar<T: ?Sized> {
    a: Cell<usize>,
    value: T,
}

unsafe fn foo<T: ?Sized>(v: &T) {
    let fake: &Bar<T> = std::mem::zeroed();

    // segfault on this line
    // we are not reading or writing uninitialized data behind the reference, 
    // but only doing pointer arithmetic. We are not reading or writing 
    // uninitialized vtable, but only copy the vtable pointer.
    let fake_val = &fake.value;
}


fn main() {
    use std::any::Any;

    let some_ref: &Any = &42 as &Any;
    unsafe …
Run Code Online (Sandbox Code Playgroud)

rust

7
推荐指数
1
解决办法
336
查看次数

添加无关的泛型参数会触发奇怪的生命周期错

我有一个特性,我想为所有实现的类型实现它std::ops::Index.这段代码有效(正如我所料):

use std::ops::Index;
use std::fmt::Display;


trait Foo {
    fn foo(&self, i: usize) -> &Display;
}

impl<C> Foo for C 
where
    C: Index<usize>,
    C::Output: Display + Sized,
{
    fn foo(&self, i: usize) -> &Display {
        &self[i]
    }
}
Run Code Online (Sandbox Code Playgroud)

(游乐场)

但是,一旦我将一个通用参数引入我的特性,我就会遇到奇怪的生命周期错误.这是代码(Playground):

trait Foo<T> {
    fn foo(&self, i: T) -> &Display;
}

impl<C, T> Foo<T> for C 
where
    C: Index<T>,
    C::Output: Display + Sized,
{
    fn foo(&self, i: T) -> &Display {
        &self[i]
    }
}
Run Code Online (Sandbox Code Playgroud)

而奇怪的错误(显然这是一个错误,在略有不同的版本中重复三次): …

lifetime rust

7
推荐指数
1
解决办法
109
查看次数

为什么添加第二个impl可以防止对参数进行反引用强制转换?

尝试将impl添加Add<char> for String到标准库时遇到了这个问题。但是我们可以轻松地复制它,而无需操作员恶作剧。我们从这个开始:

trait MyAdd<Rhs> {
    fn add(self, rhs: Rhs) -> Self;
}

impl MyAdd<&str> for String {
    fn add(mut self, rhs: &str) -> Self {
        self.push_str(rhs);
        self
    }
}
Run Code Online (Sandbox Code Playgroud)

很简单。这样,将编译以下代码:

let a = String::from("a");
let b = String::from("b");
MyAdd::add(a, &b);
Run Code Online (Sandbox Code Playgroud)

请注意,在这种情况下,第二个参数表达式(&b)具有类型&String。然后将其反强制执行&str,然后函数调用起作用。

但是,让我们尝试添加以下内容:

impl MyAdd<char> for String {
    fn add(mut self, rhs: char) -> Self {
        self.push(rhs);
        self
    }
}
Run Code Online (Sandbox Code Playgroud)

操场上的一切

现在,MyAdd::add(a, &b)上面的表达式导致以下错误:

error[E0277]: the trait bound …
Run Code Online (Sandbox Code Playgroud)

language-lawyer rust

7
推荐指数
1
解决办法
75
查看次数

如何连接 Rust Vector 的两个“&amp;str”类型元素并添加到零索引

let mut item = vec!["2", "3", "5"];
Run Code Online (Sandbox Code Playgroud)

我想连接该向量的第一个和第二个索引并替换为零索引的值。

item[0] = item[0] + item[1];
Run Code Online (Sandbox Code Playgroud)

但由于向量元素的类型&str以及连接后得到的结果是String,Rust 不允许我更新向量的值。

string vector concatenation string-literals rust

7
推荐指数
1
解决办法
1万
查看次数

在等待子进程时杀死它

我想执行另一个进程,通常想等到它完成。假设我们在线程 T1 中生成并等待进程:

let child = Command::new("rustc").spawn().unwrap();
child.wait();
Run Code Online (Sandbox Code Playgroud)

现在,如果发生特殊事件(线程 T0 正在等待),我想终止生成的进程:

if let Ok(event) = special_event_notifier.recv() {
    child.kill();
}
Run Code Online (Sandbox Code Playgroud)

但我看不出有什么办法可以做到这一点:两者killwait采用可变引用Child,因此是互斥的。打电话之后wait就没有人可以再参考了child

我找到了wait-timeout箱子,但我想知道是否还有其他方法。

rust

6
推荐指数
1
解决办法
4297
查看次数

"溢出评估需求"但这种递归根本不应该发生

这是一个冗长的例子,因为我无法进一步减少它.铁锈游乐场

use std::marker::PhantomData;
use std::ops::{Add, Sub, Mul, Div};

pub trait Scalar
    : Sized + Copy + Add<Self, Output = Self> + Sub<Self, Output = Self> + Mul<Self, Output = Self> + Div<Self, Output = Self>
    {}
impl Scalar for u32 {}

pub struct ScalarVal<T>(T) where T: Scalar;

pub trait Pixel: Sized {
    type ScalarType: Scalar;
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Gray<BaseTypeP>
    where BaseTypeP: Scalar
{
    intensity: BaseTypeP,
}

impl<BaseTypeP> Pixel for Gray<BaseTypeP>
    where BaseTypeP: Scalar
{
    type …
Run Code Online (Sandbox Code Playgroud)

generics rust

6
推荐指数
1
解决办法
268
查看次数

将枚举变体用作函数的奇怪语法是什么?

下面是mod文档给出的例子syn::parse

enum Item {
    Struct(ItemStruct),
    Enum(ItemEnum),
}

struct ItemStruct {
    struct_token: Token![struct],
    ident: Ident,
    brace_token: token::Brace,
    fields: Punctuated<Field, Token![,]>,
}

impl Parse for Item {
    fn parse(input: ParseStream) -> Result<Self> {
        let lookahead = input.lookahead1();
        if lookahead.peek(Token![struct]) {
            input.parse().map(Item::Struct)    // <-- here
        } else if lookahead.peek(Token![enum]) {
            input.parse().map(Item::Enum)      // <-- and here
        } else {
            Err(lookahead.error())
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

input.parse().map(Item::Struct)有效的普通 Rust 语法(看起来不是Item::Struct函数),还是库的一种特殊语法proc_macro?如果是后者,是否有proc_macro具体语法规则的文档?

rust rust-proc-macros

6
推荐指数
1
解决办法
1268
查看次数

为什么在存在类型参数默认值的情况下,对于HashMap和我自己的结构,类型推断的行为会有所不同?

我有一个带有两个类型参数的结构,其中一个具有默认类型:

use std::marker::PhantomData;

struct Foo<T, F = ()>(PhantomData<(T, F)>);

impl<T, F> Foo<T, F> {
    fn new() -> Self { Self(PhantomData) }
    fn foo(&self, _: T) {}
}


let foo = Foo::new();
foo.foo(0u32);
Run Code Online (Sandbox Code Playgroud)

上面的代码导致:

error[E0282]: type annotations needed
  --> src/main.rs:17:15
   |
17 |     let foo = Foo::new();
   |         ---   ^^^^^^^^ cannot infer type for `F`
   |         |
   |         consider giving `foo` a type
Run Code Online (Sandbox Code Playgroud)

我不明白为什么这里不使用默认类型。请注意,let foo: Foo<u32> = Foo::new();已经说过了-无需指定参数F。但是为什么要指定T?所以我已经很困惑。

但是后来我想起了所有这些HashMap!定义为struct HashMap<K, V, S …

rust

6
推荐指数
1
解决办法
164
查看次数