我需要一些特定于OS的代码的通用接口。这些实现相当大,它们之间没有太多共同之处,因此我的第一步是为每个实现创建单独的结构,这两种实现都具有共同的特征以使其与实现无关。
首先,这是正确的方法吗?还有其他一些方法可以使Rust变得更容易吗?
接下来,我想对此进行迭代,这意味着存储对特征的引用,而我一直无法正确理解。如果该问题的第一部分是正确的,我应该尝试针对通用特征创建一个迭代器,还是应该制作特定于操作系统的迭代器版本?
这是我尝试做的一个简单示例:
trait Thing {
#[cfg(any(target_os = "linux"))]
fn new() -> Thing {
LinuxThing {
value: 1
}
}
#[cfg(any(target_os = "macos"))]
fn new() -> Thing {
MacThing {
value: 2
}
}
fn iter(&self) -> ThingIter {
ThingIter {
thing: self
}
}
fn stuff(&self) -> u8;
}
#[cfg(any(target_os = "linux"))]
struct LinuxThing {
value: u8,
}
#[cfg(any(target_os = "macos"))]
struct MacThing {
value: u8,
}
#[cfg(any(target_os = "linux"))]
impl Thing for LinuxThing {
fn stuff(&self) -> u8 {
self.value
}
}
#[cfg(any(target_os = "macos"))]
impl Thing for MacThing {
fn stuff(&self) -> u8 {
self.value * 2
}
}
struct ThingIter<'a> {
thing: &'a Thing,
}
impl<'a> Iterator for ThingIter<'a> {
type Item = u8;
fn next(&mut self) -> Option<Self::Item> {
Some(self.stuff())
}
}
fn main() {
let thing = Thing::new();
println!("Thing: {}", thing.stuff());
let iter = ThingIter { thing: &thing };
println!("Next: {}", iter.next());
println!("Next: {}", iter.next());
println!("Next: {}", iter.next());
}
当前失败:
error[E0038]: the trait `Thing` cannot be made into an object
--> test.rs:50:5
|
50 | thing: &'a Thing,
| ^^^^^^^^^^^^^^^^ the trait `Thing` cannot be made into an object
|
= note: method `new` has no receiver
error[E0038]: the trait `Thing` cannot be made into an object
--> test.rs:10:5
|
10 | fn new() -> Thing {
| ^^^^^^^^^^^^^^^^^ the trait `Thing` cannot be made into an object
|
= note: method `new` has no receiver
error: aborting due to 2 previous errors
我是一名C语言开发人员,这意味着我已经习惯于做自己想做的事情。我喜欢Rust的概念,但是C是一个很难打破的习惯。