Rust 的 C++ ADL 重载函数替代方案?
Rust's alternative for C++ ADL overloaded functions?
有一个库提供通用函数和一些可使用的实现:
#include <iostream>
namespace lib {
struct Impl1 {};
struct Impl2 {};
void process(Impl1) { std::cout << 1; }
void process(Impl2) { std::cout << 2; }
template<typename T> void generalize(T t) { process(t); }
}
我想通过外部代码扩展它。以下是 C++ 允许执行此操作的方式:
#include <lib.h> // the previous snippet
namespace client {
struct Impl3 {};
void process(Impl3) { std::cout << 3; }
}
int main() { // test
lib::generalize(client::Impl3{}); // it couts 3
}
注意:lib
的代码对 client
的代码一无所知,并且仍然不执行动态调度。我怎样才能在我的 Rust 代码中实现同样的目标? (如果我不能,是否有类似的计划?)
当然,这正是 traits 的用途:
pub mod lib {
pub trait Impl {
fn process(&self);
}
pub struct Impl1 {}
pub struct Impl2 {}
impl Impl for Impl1 {
fn process(&self) {
println!("1");
}
}
impl Impl for Impl2 {
fn process(&self) {
println!("2");
}
}
pub fn generalize<T: Impl>(t: T) {
t.process();
}
}
mod client {
pub struct Impl3 {}
impl super::lib::Impl for Impl3 {
fn process(&self) {
println!("3");
}
}
}
fn main() {
lib::generalize(client::Impl3 {});
}
在 Playground 上查看。
Rust 更严格,可能需要 lib
才能玩得很好。它可以通过定义一个 trait
来实现,该 trait
定义了支持 process
:
的东西
trait Processable {
fn process(self);
}
struct Impl1 {}
impl Processable for Impl1 {
fn process(self) {/*TODO*/}
}
fn generalize<T: Processable>(t: T) { t.process(); }
然后,Processable
可以被“外人”用来通知系统Impl3
满足要求的接口:
struct Impl3 {}
impl Processable for Impl3 {
fn process(self) {/*TODO*/}
}
那么,generalize
也可以调用Impl3
有一个库提供通用函数和一些可使用的实现:
#include <iostream>
namespace lib {
struct Impl1 {};
struct Impl2 {};
void process(Impl1) { std::cout << 1; }
void process(Impl2) { std::cout << 2; }
template<typename T> void generalize(T t) { process(t); }
}
我想通过外部代码扩展它。以下是 C++ 允许执行此操作的方式:
#include <lib.h> // the previous snippet
namespace client {
struct Impl3 {};
void process(Impl3) { std::cout << 3; }
}
int main() { // test
lib::generalize(client::Impl3{}); // it couts 3
}
注意:lib
的代码对 client
的代码一无所知,并且仍然不执行动态调度。我怎样才能在我的 Rust 代码中实现同样的目标? (如果我不能,是否有类似的计划?)
当然,这正是 traits 的用途:
pub mod lib {
pub trait Impl {
fn process(&self);
}
pub struct Impl1 {}
pub struct Impl2 {}
impl Impl for Impl1 {
fn process(&self) {
println!("1");
}
}
impl Impl for Impl2 {
fn process(&self) {
println!("2");
}
}
pub fn generalize<T: Impl>(t: T) {
t.process();
}
}
mod client {
pub struct Impl3 {}
impl super::lib::Impl for Impl3 {
fn process(&self) {
println!("3");
}
}
}
fn main() {
lib::generalize(client::Impl3 {});
}
在 Playground 上查看。
Rust 更严格,可能需要 lib
才能玩得很好。它可以通过定义一个 trait
来实现,该 trait
定义了支持 process
:
trait Processable {
fn process(self);
}
struct Impl1 {}
impl Processable for Impl1 {
fn process(self) {/*TODO*/}
}
fn generalize<T: Processable>(t: T) { t.process(); }
然后,Processable
可以被“外人”用来通知系统Impl3
满足要求的接口:
struct Impl3 {}
impl Processable for Impl3 {
fn process(self) {/*TODO*/}
}
那么,generalize
也可以调用Impl3