是否有可能写出一个类型特征,比如说is_callable<T>一个对象是否已operator()定义?如果调用运算符的参数事先已知,则很容易,但在一般情况下则不行.当且仅当至少有一个重载调用运算符被定义时,我希望特征返回true.
这个问题是相关的,并且有一个很好的答案,但它不适用于所有类型(仅限于 - 可int转换类型).此外,std::is_function工作,但只适用于正确的C++函数,而不是函子.我正在寻找更通用的解决方案.
在尝试Any更好地理解这个特性的同时,我看到它有一个impl阻碍特质本身.我不明白这个结构的目的,或者即使它有一个特定的名称.
我用"普通"特征方法和impl块中定义的方法做了一个小实验:
trait Foo {
fn foo_in_trait(&self) {
println!("in foo")
}
}
impl dyn Foo {
fn foo_in_impl(&self) {
println!("in impl")
}
}
impl Foo for u8 {}
fn main() {
let x = Box::new(42u8) as Box<dyn Foo>;
x.foo_in_trait();
x.foo_in_impl();
let y = &42u8 as &dyn Foo;
y.foo_in_trait();
y.foo_in_impl(); // May cause an error, see below
}
Run Code Online (Sandbox Code Playgroud)
编者注
在Rust的版本中,包括Rust 1.15.0,该行
y.foo_in_impl()会导致错误:Run Code Online (Sandbox Code Playgroud)error: borrowed value does not live long enough --> src/main.rs:20:14 …
我有一个特点叫Sleep:
pub trait Sleep {
fn sleep(&self);
}
Run Code Online (Sandbox Code Playgroud)
我可以Bed为每个结构提供不同的实现,但事实证明大多数人以很少的方式睡觉.你可以睡在床上:
pub trait HasBed {
fn sleep_in_bed(&self);
fn jump_on_bed(&self);
}
impl Sleep for HasBed {
fn sleep(&self) {
self.sleep_in_bed()
}
}
Run Code Online (Sandbox Code Playgroud)
如果你露营,你可以睡在帐篷里:
pub trait HasTent {
fn sleep_in_tent(&self);
fn hide_in_tent(&self);
}
impl Sleep for HasTent {
fn sleep(&self) {
self.sleep_in_tent()
}
}
Run Code Online (Sandbox Code Playgroud)
有一些古怪的案例.我有一个可以靠墙站着睡觉的朋友,但大多数人大多数时候会陷入一些简单的情况.
我们定义一些结构并让它们Sleep:
struct Jim;
impl HasBed for Jim {
fn sleep_in_bed(&self) {}
fn jump_on_bed(&self) {}
}
struct Jane;
impl HasTent for Jane {
fn …Run Code Online (Sandbox Code Playgroud) 我最近在PHP中遇到了Traits,我正试图理解它们.在我的研究期间,我偶然发现了Stack Overflow这个问题:Traits vs. Interfaces.接受的答案提到以下内容:
接口定义了实现类必须实现的一组方法.
当使用特征时,方法的实现也会出现 - 这在接口中不会发生.
到目前为止这么好,但这听起来就像接口和抽象类之间的区别.所以这为我提出了一个后续问题:
我知道我只能从一个抽象类扩展,另一方面可以使用任何数量的特征.但这真的是唯一的区别吗?我仍然不完全了解特征及其用途.
为什么我们不允许在PHP中使用类扩展Traits?
例如:
Trait T { }
Class C use T {}
/* or */
Class C extends T {}
Run Code Online (Sandbox Code Playgroud)
这种语法有没有潜在的冲突?我不这么认为.
我阅读了Scala中的Programming编程部分abstract override,但是我仍然对这些修饰符的加入所表示的内容感到困惑.使用这些修饰符的代码片段粘贴在下面:
trait Doubling extends IntQueue {
abstract override def put(x: Int) { super.put(2 * x) }
}
Run Code Online (Sandbox Code Playgroud)
特别是,我对abstract这种情况的目的感到困惑,以及为什么我们不能简单地用override关键字实现预期的结果.如果我们没有包含电话super,我们是否需要关键字abstract?为什么或者为什么不?我正在寻找这个关键字组合的详细解释,因为它与可堆叠特征有关.
我刚刚深入研究了Rust,并希望制作一些通用的基本数学函数.我有以下is_prime功能:
fn is_prime(n: i64) -> bool {
if n == 2 || n == 3 {
return true;
} else if n % 2 == 0 || n % 3 == 0 {
return false;
}
let mut i = 5i64;
let mut w = 2i64;
while i*i <= n {
if n % i == 0 {
return false;
}
i += w;
w = 6 - w;
}
true
}
Run Code Online (Sandbox Code Playgroud)
那么将会对我来说,能够通过isize,i64,usize …
我是Traits的新手,但是我的函数中有很多重复的代码,我想使用Traits来减少代码的混乱.我Traits在我的Http目录中创建了一个名为Trait的目录BrandsTrait.php.它所做的只是呼吁所有品牌.但是当我尝试在我的产品控制器中调用BrandsTrait时,如下所示:
use App\Http\Traits\BrandsTrait;
class ProductsController extends Controller {
use BrandsTrait;
public function addProduct() {
//$brands = Brand::all();
$brands = $this->BrandsTrait();
return view('admin.product.add', compact('brands'));
}
}
Run Code Online (Sandbox Code Playgroud)
它给我一个错误,说方法[BrandsTrait]不存在.我想初始化一些东西,或者用不同的方式称呼它?
这是我的 BrandsTrait.php
<?php
namespace App\Http\Traits;
use App\Brand;
trait BrandsTrait {
public function brandsAll() {
// Get all the brands from the Brands Table.
Brand::all();
}
}
Run Code Online (Sandbox Code Playgroud) 为什么下面的错误?如何解决它?
编辑:我假设因为A和B编译成(接口,类)对,所以在编译C时选择正确的静态方法调用是一个问题.我希望优先级按顺序排列.
scala> trait A { def hi = println("A") }
defined trait A
scala> trait B { def hi = println("B") }
defined trait B
scala> class C extends B with A
<console>:6: error: error overriding method hi in trait B of type => Unit;
method hi in trait A of type => Unit needs `override' modifier
class C extends B with A
scala> trait A { override def hi = println("A") }
<console>:4: error: method hi overrides nothing …Run Code Online (Sandbox Code Playgroud) 斯威夫特是否有一种混合特征的方式,斯卡拉?关于使用扩展来向现有类添加协议的Swift小册子的部分非常接近.但是,由于协议不能包含实现,因此不能将其用于将代码混合到类中.还有另外一种方法吗?
traits ×10
php ×3
rust ×3
scala ×2
c++ ×1
laravel ×1
laravel-5.2 ×1
mixins ×1
oop ×1
overriding ×1
swift ×1
type-traits ×1