• 罗杰
    2021-10-20
    impl Iterator for Equation<Quadratic> 判断返回 None 的地方是不是应该写成 `if self.current >= u16::MAX as u32`,不然会有逻辑错误。

    作者回复: 👍 是的,非常厉害!这个 bug 我也是又看了一遍代码才发现。

    
    9
  • Marvichov
    2021-10-18
    和老师的对应下... 1. 使用泛型参数延迟数据结构的绑定; 2. 使用泛型参数和 PhantomData,声明数据结构中不直接使用,但在实现过程中需要用到的类型 3. 使用泛型参数让同一个数据结构对同一个 trait 可以拥有不同的实现。 1. 面向interface编程; 只不过静态多态 2. 引入自由参数 -> 大部分impl共享; 剩下的, 根据自由参数类型的不同做template specialization -> 比如tag struct -> 本质还是代码共享 3. NewTypePattern; 一套代码给多个不同的type共用; 这个blog里面的例子比较生动: https://www.greyblake.com/blog/2021-10-11-phantom-types-in-rust/; golang里面也经常用kilometer, mile来做例子, 类似于`type mile i32`;

    作者回复: 👍

    
    6
  • Marvichov
    2021-10-18
    Cpp里面用tag和多generic param的例子也很多… 比如Cpp的iterator, 多个泛型做参数, 不需要PhantomData; template< class Category, // tag data, 类似于 AsyncProstReader D class T, class Distance = std::ptrdiff_t, class Pointer = T*, class Reference = T& > struct iterator; 所以, 感觉PhantomData的主要用途是compile time ownership check; 我的疑问也就主要集中在ownership... 问题1: from PhantomData doc: > Adding a PhantomData field to your type tells the compiler that your type acts as though it stores a value of type T, even though it doesn’t really. 不太明白, 为啥需要ownership. 比如AsyncProstReader的T是约束R的return type的, 按理说不用own T; 而且into和dest member全程没被调用过 /// A wrapper around an async reader that produces an asynchronous stream of prost-decoded values #[derive(Debug)] pub struct AsyncProstReader<R, T, D> { reader: R, pub(crate) buffer: BytesMut, into: PhantomData<T>, dest: PhantomData<D>, } 如果不需要对T, D的ownership, 为啥不来个`PhantomDataNotOwned`来满足这样的场景: 不需要ownership, 但是这个generic type T不是多余的呢? ---- 问题2: > This information is used when computing certain safety properties. 这句目前理解不了…假设对T有ownership, 没看出有啥特殊的safety需求
    展开

    作者回复: 我的理解是大部分时候 PhantomData 跟其它语言的 Phantom Type 是一个作用,为数据结构提供声明时没用用到,但在实现时需要用到的类型。因为这里你实实在在就只用 T 来保证类型的正确性,并没有涉及到 owership。 但在有些场合下,比如 Unique<T>,这里,如果没用 PhantomData<T>的话,你想想 Unique<T> 是否 own T?并不 own,因为 pointer 是一个指针类型,所以从类型上,Unique<T> 不 own T,但这里 Unique<T> 应该 own T 才对。所以 Rust 使用 PhantomData 来表述这个作用,见:https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data ```Rust pub struct Unique<T: ?Sized> { pointer: *const T, _marker: PhantomData<T>, } ``` 这属于 PhantomData 的高级用法,大部分时候我们用类型系统解决问题需要使用 PhantomData 时,都是大家在其他语言中惯常的用法,所以我没有提这个 owership 的用法。

    共 2 条评论
    4
  • Custer
    2021-10-28
    1. 参数 F 是一个闭包,接收 Self::Item,返回 Fut 类型; 2. 参数 Fut 是一个 Future<Output=()>; 所以 f 是一个闭包接收 Self::Item 闭包的返回值是 Future<Output=()> 使用参考源代码: ```rust .for_each_concurrent( /* limit */ 2, |rx| async move { rx.await.unwrap(); } ) ```

    作者回复: 👍

    
    
  • Geek_7c0961
    2022-05-16
    老师现在implement trait 用在返回值的类型了,那么 trait obejct还有什么用处么?它的性能那么差. https://doc.rust-lang.org/rust-by-example/trait/impl_trait.html
    
    1
  • A.Y.
    2022-05-07
    关于第三点使用场景,似乎可以用于替代其他面向对象语言中有而rust不支持的类继承。
    
    1
  • 渡鸦10086
    2022-01-16
    关于思考题: f 是一个闭包,以 `Self::Item` 类型作为输入,以一个实现了 `Future` trait 的类型 Fut 作为输出,其中`Future` 的关联类型 `Output` 是 unit 类型
    
    1
  • 🐲礁sir
    2022-09-11 来自四川
    终于明白substrate的frame/executiv/src/lib.rs里面这段代码的用意:
    共 1 条评论
    
  • zahi
    2022-08-14 来自北京
    phantom type 的例子,感觉像java中的继承。
    
    