在计算机编程中,特征是一组方法,用作“构建面向对象程序的简单概念模型”
我正在尝试实现显示和调试特征的特征,但 Rust 的响应是相互冲突的实现。 这是我的代码: pub 特征 AsString { fn as_string(self) -> 字符串; } 暗示&...
定义一个通用函数,它将接受对实现特定特征的任何可迭代事物的借用
我有一个特质和一个实现该特质的东西: 特征 HasPosition2D { fn x(&self) -> &i32; fn y(&self) -> &i32; fn x_mut(&mut self) -> &mut i32; ...
我正在为自己构建一个解析库,并且我发现了两种声明的特征边界类型之间的关键区别。 采取以下特征: pub 特征可解析:FromStr {} 随着...
我扩展了具有特征的类型,为什么我的 Vec<impl ThatTrait> 不接受实现该特征的类型?
我有一个特征输入,它向字符串和 u64 添加了 to_custom_bytes() 方法。 特征输入{ fn to_custom_bytes(&self) -> Vec; } impl 输入 u64 { fn to_custom_bytes(&
在 Rust 中,没有函数的类型,而是 Fn 特征,如下所示: 特征 Fn { fn 调用(self, args: A) -> R; } 那么函数的类型可以...
我试图了解如何在 Rust 中实现通用特征。 虽然我看过很多例子,但这些例子与特定用途(例如基因组突变子)太相关,我无法理解
说我有以下特质: 特质 SayHello { fn say_hello(self) -> 字符串; } 为什么我可以这样做: fn say_hello_twice(this: impl SayHello) -> String { 让 said_hello = 这个。
具有如下特征 特质我的特质 { val国家:字符串, val状态:字符串, val commune:字符串=“无” } 现在实施 MyTrait 案例类 ImplementTrait( ...
我定义了以下特征: 酒吧特质 TItem { // 一些函数 } 我有两个结构 TArray 和 TObject: 为 TArray 实现 TItem { // 一些函数 } 为 TObject 实现 TItem { // ...
如何从结构类型 T 转换为结构类型 U,这两者都实现了 Rust 中的特定特征
我定义了以下特征: 酒吧特质 TItem { // 一些函数 } 我有两个结构 TArray 和 TObject: 为 TArray 实现 TItem { // 一些函数 } 为 TObject 实现 TItem { // ...
为什么要通过 where 子句中的通用特征来约束单位类型(如 `where () : Trait<…>`)?
今天我在这里遇到了这种语法: https://github.com/binator/self/tree/80ba2ade?tab=readme-ov-file#example fn hex_primary(流:流)-> 已解析 今天我在这里遇到了这种语法: https://github.com/binator/self/tree/80ba2ade?tab=readme-ov-file#example fn hex_primary<Stream, Context>(stream: Stream) -> Parsed<u8, Stream, Context> where (): IntRadixParse<Stream, Context, u8>, { uint_radix(2, Radix::HEX).parse(stream) } 对我来说,它看起来像“绑定在单位类型(又名空元组)”,但我无法理解它。默认情况下,单一类型不会实现每个特征,不是吗?不幸的是,官方文档太模糊且不够完整(同时过于冗长),我找不到任何相关内容。 原始 RFC for where 子句也提到了这个语法,但没有正确的解释: https://rust-lang.github.io/rfcs/0135-where.html#alternatives fn increment<T>(c: T) -> T where () : Add<int,T,T> { 1 + c } 但除此之外,我知道这样的界限不仅可以在特征泛型中指定。 那么它是什么,什么时候使用,为什么需要它,它解决哪些问题? 在代码片段中,where子句用于缩小通用约束范围。不是定义所有约束,而是使用 (): IntRadixParse<Stream, Context, u8>,这意味着无论 Stream 和 Context 具有什么类型,它们都必须遵循 IntRadixParse 的约束。 特质IntRadixParse是 pub trait IntRadixParse<Stream, Context, Token: 'static> = where Stream: Streaming, <Stream as Streaming>::Item: Into<u8>, Token: CheckedAdd + CheckedMul + CheckedSub + Zero + Copy + Debug, Context: Contexting<IntRadixAtom<Token>>, Context: Contexting<BaseAtom<u8>>, Context: Contexting<CoreAtom<Stream>>, Context: Contexting<UtilsAtom<Stream>>, u8: AsPrimitive<Token>; 注意:它使用 trait 别名不稳定功能 因此,要编写没有奇怪的单位约束语法的函数,它会是这样的 fn hex_primary<Stream, Context>(stream: Stream) -> Parsed<u8, Stream, Context> where Stream: Streaming, <Stream as Streaming>::Item: Into<u8>, Context: Contexting<IntRadixAtom<u8>>, Context: Contexting<BaseAtom<u8>>, Context: Contexting<CoreAtom<Stream>>, Context: Contexting<UtilsAtom<Stream>>, { uint_radix(2, Radix::HEX).parse(stream) } 注意:函数中Token替换为u8 另一个示例: #![feature(trait_alias)] trait A<T> = where T: B; // Similar to `IntRadixParse` which // shows that T should implement B /// trait B with a method a trait B { fn a(self); } /// implemented for unit impl B for () { fn a(self) {} } fn a<T>(a: T) where (): A<T> { a.a() // T gets inferred to have implemented B and `a()` can be called } fn main() {} (): IntRadixParse<Stream, Context, u8>确实是单位类型的界限。它之所以有效,是因为特征别名1的定义如下: pub trait IntRadixParse<Stream, Context, Token: 'static> = where …; // where bounds omitted for brevity 特别注意where之前缺失的特征,没有特征,所以在条件成立的情况下,这个别名是没有任何特征的别名。 每种类型都满足“实现一组空的特征”,因此编译器唯一需要证明的就是边界。简而言之,因为 Self 没有被引用,并且没有任何特征可以满足,所以您可以在那里编写任何类型,而不是单位 () 。当类型不重要时,Rust 程序员经常使用单位。 这使得特征别名对于缩写一堆边界非常有用,就像 Timsib Adnap 的答案中所解释的那样 特质别名不稳定
Rust 中的 `where () : Trait<…>` 是什么?
今天我在这里遇到了这种语法: https://github.com/binator/self/tree/80ba2ade?tab=readme-ov-file#example fn hex_primary(流:流)-> 已解析 今天我在这里遇到了这种语法: https://github.com/binator/self/tree/80ba2ade?tab=readme-ov-file#example fn hex_primary<Stream, Context>(stream: Stream) -> Parsed<u8, Stream, Context> where (): IntRadixParse<Stream, Context, u8>, { uint_radix(2, Radix::HEX).parse(stream) } 对我来说,它看起来像“绑定在单位类型(又名空元组)”,但我无法理解它。默认情况下,单一类型不会实现每个特征,不是吗?不幸的是,官方文档太模糊且不够完整(同时过于冗长),我找不到任何相关内容。 原始 RFC for where 子句也提到了这个语法,但没有正确的解释: https://rust-lang.github.io/rfcs/0135-where.html#alternatives fn increment<T>(c: T) -> T where () : Add<int,T,T> { 1 + c } 但除此之外,我知道这样的界限不仅可以在特征泛型中指定。 那么它是什么,什么时候使用,为什么需要它,它解决哪些问题? 在代码片段中,where子句用于缩小通用约束范围。不是定义所有约束,而是使用 (): IntRadixParse<Stream, Context, u8>,这意味着无论 Stream 和 Context 具有什么类型,它们都必须遵循 IntRadixParse 的约束。 特质IntRadixParse是 pub trait IntRadixParse<Stream, Context, Token: 'static> = where Stream: Streaming, <Stream as Streaming>::Item: Into<u8>, Token: CheckedAdd + CheckedMul + CheckedSub + Zero + Copy + Debug, Context: Contexting<IntRadixAtom<Token>>, Context: Contexting<BaseAtom<u8>>, Context: Contexting<CoreAtom<Stream>>, Context: Contexting<UtilsAtom<Stream>>, u8: AsPrimitive<Token>; 注意:它使用 trait 别名不稳定功能 因此,要编写没有奇怪的单位约束语法的函数,它会是这样的 fn hex_primary<Stream, Context>(stream: Stream) -> Parsed<u8, Stream, Context> where Stream: Streaming, <Stream as Streaming>::Item: Into<u8>, Context: Contexting<IntRadixAtom<u8>>, Context: Contexting<BaseAtom<u8>>, Context: Contexting<CoreAtom<Stream>>, Context: Contexting<UtilsAtom<Stream>>, { uint_radix(2, Radix::HEX).parse(stream) } 注意:函数中Token替换为u8 另一个示例: #![feature(trait_alias)] trait A<T> = where T: B; // Similar to `IntRadixParse` which // shows that T should implement B /// trait B with a method a trait B { fn a(self); } /// implemented for unit impl B for () { fn a(self) {} } fn a<T>(a: T) where (): A<T> { a.a() // T gets inferred to have implemented B and `a()` can be called } fn main() {} 语法(): IntRadixParse<Stream, Context, u8>之所以有效,是因为特征别名1的定义如下: pub trait IntRadixParse<Stream, Context, Token: 'static> = where …; // where bounds omitted for brevity 特别注意where之前缺失的特征,没有特征,所以在条件成立的情况下,这个别名是没有任何特征的别名。 每种类型都满足“实现一组空的特征”,因此唯一剩下的就是边界。简而言之,您可以在那里编写任何类型,而不是单位(),当类型不重要时,Rust 程序员经常使用单位。 这使得特征别名对于缩写一堆边界非常有用,如 Timsib Adnap 所演示的 特质别名不稳定
今天我在这里遇到了这种语法: https://github.com/binator/self/tree/80ba2ade?tab=readme-ov-file#example fn hex_primary(流:流)-> 已解析 今天我在这里遇到了这种语法: https://github.com/binator/self/tree/80ba2ade?tab=readme-ov-file#example fn hex_primary<Stream, Context>(stream: Stream) -> Parsed<u8, Stream, Context> where (): IntRadixParse<Stream, Context, u8>, { uint_radix(2, Radix::HEX).parse(stream) } 对我来说,它看起来像“绑定在单位类型(又名空元组)”,但我无法理解它。默认情况下,单一类型不会实现每个特征,不是吗?不幸的是,官方文档太模糊且不够完整,我找不到任何相关内容。 原始 RFC for where 子句也提到了这个语法,但没有正确的解释: https://rust-lang.github.io/rfcs/0135-where.html#alternatives fn increment<T>(c: T) -> T where () : Add<int,T,T> { 1 + c } 但除此之外,我知道这样的界限不仅可以在特征泛型中指定。 那么它是什么,什么时候使用,为什么需要它,它解决哪些问题? 是的,这是单位类型的限制。 单位类型并没有实现许多有用的特征(尽管它确实实现了一些,例如Debug),但是在 Rust 中,你可以实现外来类型的特征,只要该特征是你自己的,或者在有限的情况下,即使该特征不是你的,但它的一些通用参数是。所以这个库可能定义了 IntRadixParse 类型,并为单位类型实现它。
在我的应用程序中,我希望有一个 EventPersister 特征,它定义持久事件的抽象,然后有各种实现,例如,将事件持久保存在内存中、文件中
从 php 中的特征访问类常量会在 VScode 中出现错误
我在 laravel 中的同一个 App 文件夹中有一个类和一个特征 我的类.php 我在 laravel 中的同一个 App 文件夹中有一个类和一个特征 MyClass.php <?php namespace App; class MyClass { use myTrait; CONST MY_CONST = 'CONST'; public function showConst() { echo $this->myTraitMethod(); } } MyTrait.php <?php namespace App; class MyTrait { public function myTraitMethod() { return self::MY_CONST; // Undefined class constant 'MY_CONST' return static::MY_CONST; // Undefined class constant 'MY_CONST' return MyClass:MY_CONST; // This is the only one that works but I'm forcing the class name } } 问题是我无法访问 MY_CONST 除非我强制使用父类名称,这对我来说不是解决方案。 更新 问题出在 vscode 上,我的意思是代码在 self 和 static 下都运行良好,但 vscode 返回错误 Undefined class constant 'MY_CONST' 我更新了问题标题以匹配实际问题 在 PHP 中,特征充当可重用的代码块,可以包含在多个类中。这种方法允许开发人员在各个类之间共享方法,而不受继承的限制,继承仅支持单个父类。然而,有一个缺点:特征不能直接引用包含它们的类中定义的常量。存在这种限制是因为常量特定于每个类,并且对于特征本身并不可见。 在您的原始设置中: 您有一个名为 MyClass 的类,它定义了常量 MY_CONST。 您想在名为 MyTrait 的特征中使用此常量。 但是,直接从特征访问 MY_CONST 会导致错误,除非类名被硬编码,这具有限制性并降低了特征的灵活性。 解决方法 为了解决这个问题,我们可以在特征中引入一个抽象方法。抽象方法不包含任何实现,但强制任何类使用该特征来定义它。通过这样做,我们创建了一种方法,让类将常量的值传递给特征,而特征不需要直接访问常量本身。
Rust 支持特征继承,如下: 酒馆特征 A {} 酒吧特质 B: A {} B:A意味着如果某个类型T实现了B,那么它也需要实现A中的所有方法。 但今天我看到了以下...
我正在用 Rust 编写一个玩具数据库实现,但我无法绕过这个对象安全的特征要求。我基本上想要一种表示具有
我有以下 Rust 代码。 特征 X<'a> { fn x(&self) -> &'a [f64]; } 结构拥有{ x:Vec, } 结构参考<'a> { x: &'a[f64], } 我愿意
我想编写一个接受具有 ToString 特征的类型的迭代器的函数。 我的想法是: fn parse(mut args: T) -> 结果 我想编写一个函数,接受具有 Iterator 特征的类型的 ToString。 我的想法: fn parse<T: Iterator /* ?T::Item : ToString? */>(mut args: T) -> Result<String, String> { match args.next() { Some(x) => x.to_string(), None => String::from("Missing parameter"), } } 是的,您可以使用 where 子句来做到这一点: fn parse<T: Iterator>(mut args: T) -> Result<String, String> where <T as Iterator>::Item: ToString, { // .... } 或者,由于这里 Item 的含义是明确的,因此界限可以是: where T::Item: ToString 您可以使用 Item = 语法: fn parse<I: ToString, T: Iterator<Item = I>>(mut args: T) -> Result<String, String> 这允许您使用 impl 语法进一步简化: fn parse<T: Iterator<Item = impl ToString>>(mut args: T) -> Result<String, String> 最后: fn parse(mut args: impl Iterator<Item = impl ToString>) -> Result<String, String> 我认为这是一个更具可读性的替代方案。 从 Rust 1.79 开始,您可以将绑定直接放置在关联的 Item 类型上,因此您可以像这样定义 parse(): fn parse<T: Iterator<Item: ToString>>(mut args: T) -> Result<String, String> { ... } 甚至像这样: fn parse(mut args: impl Iterator<Item: ToString>) -> Result<String, String> { ... }