在计算机编程中,特征是一组方法,用作“构建面向对象程序的简单概念模型”
假设我想引入一个具有两种方法的特征,这两种方法在某种意义上是相互依赖的,其中一个可以默认使用另一个来实现。例如: 使用 std::io; 特质
我刚刚学习 Rust,在选项内向上转换特征引用时遇到一些问题。我想将其作为参考传递以减少开销。 基本思路如下: 我有一些物体(孩子)
在 PHP 中测试特征时,我有点困惑为什么要引入特征。我做了一些小实验。首先我直接在类中调用特征方法 在 PHP 中测试特征时,我有点困惑为什么要引入特征。我做了一些小实验。首先我直接在类中调用特征方法 <?php trait HelloWorld { public function sayHello() { echo 'Hello World!'; } } class TheWorldIsNotEnough { use HelloWorld; public function sayHellos() { $o = new HelloWorld(); $o->sayHello(); } } $o = new TheWorldIsNotEnough(); $o->sayHellos(); ?> 我收到一个错误 Fatal error: Cannot instantiate trait HelloWorld in C:\xampp\htdocs\test.php on line 35 但是当我这样做的时候 <?php trait HelloWorld { public function sayHello() { echo 'Hello World!'; } } class MyHelloWorld { use HelloWorld; } class TheWorldIsNotEnough { use HelloWorld; public function sayHellos() { $o = new MyHelloWorld(); $o->sayHello(); } } $o = new TheWorldIsNotEnough(); $o->sayHellos(); ?> 我能够调用特征方法,结果显示“Hello World!”。 那么使用 Traits 的优点是什么?它与抽象类有何不同?请帮助我理解用法。谢谢。 Traits 不应被实例化。它们只是代码部分,您可以通过 use 在类中重用它们。您可以想象,trait代码会扩展并成为您的类的一部分。甚至令人悲伤的是: 特征本质上是语言辅助的复制和粘贴。 所以你的例子应该像这样工作: <?php trait HelloWorld { public function sayHello() { echo 'Hello World!'; } } class TheWorldIsNotEnough { use HelloWorld; public function sayHellos() { // your trait defines this method, so now you can // think that this method is defined in your class directly $this->sayHello(); } } $o = new TheWorldIsNotEnough(); $o->sayHellos(); //or simply $o->sayHello(); ?> 感谢所有发布答案的人,但经过大量研究后得到了我真正寻找的答案。我的问题是是什么使 Traits 与抽象类、继承等现有方法不同。在类内部调用时实例化它是可以的,但最大的区别是我们可以通过这种方式在类中包含多个特征 use class1, class2; 如果两个类中存在相同的方法并且我们想使用 class2 中的方法时发生冲突,我们会这样做 use class1, class2 { class2::method1 insteadof class1; } 甚至特征也可以有多个这样定义的特征: trait Class1 { use trait1, trait2; } 与继承不同;如果特征具有静态属性,则使用该特征的每个类都具有这些属性的独立实例。 检查此链接http://php.net/manual/en/language.oop5.traits.php#107965 特征与继承的另一个区别是特征中定义的方法可以访问它们所使用的类的方法和属性,包括私有的。 http://php.net/manual/en/language.oop5.traits.php#109508. 与接口实现不同的是,所有特征方法都可以访问而无需再次定义。 好吧,这可能不是正确的方法,但我想出了一种如何使用 Traits 的方法,以及为什么它在某些情况下对我的项目更好。它们是类的一种扩展。如果您熟悉 CakePHP,这些 Traits 让我想起模型的行为或控制器的组件。只要查一下就可以了:-) 抽象类略有不同,因为您可以像这样使用它进行继承: abstract class HelloWorld { public function sayHello() { echo "Hello World!"; } abstract public function doFunnyStuff(); abstract public function doMoreFunnyStuff(); } class ConcreteHelloWorld extends HelloWorld { public function doFunnyStuff() { echo "Funny Hello!"; } public function doMoreFunnyStuff() { echo "More Funny Hello!"; } } $o = new ConcreteHelloWorld(); $o->sayHello(); // common property $o->doFunnyStuff(); // specialy implemented property $o->doMoreFunnyStuff(); // specialy impelemented property 特质更像是一个类的扩展。我正在 MVC 框架中使用 Traits 以这种方式扩展带有日志记录的类: trait Logger { public function saveLog($kindOf, $messasge, $serverity) { some_connect_to_DB_pseudo_code(); $sqlQuery = "INSERT INTO log (kindof, message, serverity) VALUES (".$kindof.", ".$message.", ".$serverity.")"; mysql_query($sqlQuery); // deprecated :-) } } class Controller extends AppController { use Logger; public function someAction($params) { $this->saveLog("CALL", __METHOD__." - started some Action with params: ".$params, 0); ... ... } } 它非常方便,因为我在每个类中都使用它,而且我不必在必须连接到数据库并生成 SQL 查询的地方再次编写所有这些行。由于我在整个 MVC 框架中拥有大量继承,因此我不必将 Logger 作为某些父类包含在内。只需将其与“use”关键字一起放入任何应该能够将日志信息发送到数据库的类中即可。 同样的事情对我来说也适用于调试消息,我只需写这样的东西: $this->debug("WARNING", $message); 我的调试特征正在制作一条格式良好的警告消息:-)希望它有助于理解。 Abstract和Trait类之间唯一的共同点是无法单独实例化a Trait/an Abstract。 但他们的目的不同。 Trait 仅旨在以细粒度且一致的方式对功能进行分组。它是通过使开发人员能够在生活在不同类层次结构中的多个独立类中减少单继承的一些限制,其中类只是提供一种继承模板并强制继承类实现抽象方法。
我一直在编写一个数据存储模块作为技术练习,以掌握一些基本的 Rust,但我在实现将不同类型转换为特征的过程中遇到了一些问题......
将泛型中的 Box<T> 转换为 rust 中的 Box<dyn Trait>
>到容器> //例子 fn 主() { 让容器:Container> = Contai...
我正在开发一个 Rust 项目,在该项目中我定义了几个特征(A1、A2 和 A3),每个特征都有多个实现。我还有一个 struct Algo,它采用基于这些特征的泛型。我
pub mod 的东西{ pub 特征 Clone2:克隆 {} 为 Vec {} 实现 Clone2 } fn 主() { 让 x: Vec = Default::default(); 让 _ = 东西::Clone2::clo...
我有一个泛型结构 Test,它具有实现特征的默认泛型类型参数。这是我的代码: 酒吧特质实施{ fn 测试(); } pub 结构 FirstImpl; impl 实现
如何从以下代码中的 a 变量获取 Box 或 &B 或 &Box: 特征 A {} 结构B; 为 B 实现 A {} fn 主() { 让 mut a: Box = Box::new(B); 让...
我在 C++ 方面经验丰富,并开始尝试 Rust。 尝试实现一些简单的通用函数时,我遇到了以下问题: 使用 std::ops::BitAnd; 使用 std::cmp::Eq;
我有一个特征 MyTrait,并且我希望所有特征对象 &dyn MyTrait 都可以相互比较,并且不能与其他任何东西进行比较。我现在基于如何测试特征对象之间的相等性?。
有没有办法实现下面的功能? 特征 X {} 结构体A; 结构B; 为 A 实现 X {} 为 B {} 实现 X /// 只保留A类型的元素 fn 过滤器(列表:Vec>)->...
在此代码中,MyDeref 与标准库中 Deref 的定义匹配,MemoryView(从更复杂的示例简化而来)也几乎如此。 酒吧特质 MyDeref { 输入目标:?S...
这是在特征中使用异步函数的最小示例: 使用 async_trait::async_trait; 宏规则!默认_f { () => { 异步 fn f() -> i32 { 0 } }; } #[async_trait]...
有没有办法让此代码的版本使用特征中定义的默认值? Trait A { // 或者`抽象类A` def x: 字符串 def y: 整数 = 1 } 最终案例类别 B(x: ...
我有以下代码: 无论如何使用; 结构内部值; 枚举值{ 整数(i32), 其他(内在价值), } 为 &InnerValue 实现 TryFrom<&Value> { 类型错误=无论如何::错误;...
如何简化这段代码?在面向对象编程之后,我仍然无法理解 Rust 的特征和结构。 结构体玩家{ 实体:实体, 马力:i32, 攻击力:i32 } 结构箱{ 实体:实体...
我对 ms Scala 测试有以下设置,其中我有一个如下所示的特征: 特征 CPODBTestContainerSpec 扩展 AnyFlatSpecLike 和 TestContainerForAll { .... .... } 抽象类...
最初我使用本教程作为一些练习代码的参考。 经过几个小时的故障排除后,我只是简单地按原样尝试了该页面上的代码。 https://doc.rust-lang.org/book/ch17-02-trait-
当我将 HashMap 放入结构中时,为什么编译器会说 Hash 未实现?
我试图在我的结构中以非常基本的方式使用 HashMap,但我对这个错误感到困惑......我错过了什么? 错误[E0277]:特征绑定`HashMap<&str, &T>:Hash`未满足...