英文:
using rust newtype as generic type param
问题
I am trying to avoid specifying multiple traits on each use of generic type T. Can I use the newtype idiom to specify bounds once? This works but I'll have the where ...
on each function.
fn prn<T>(arg: T)
where
T: std::fmt::Debug + Copy,
{
println!("{:?}", arg);
}
fn main() {
let x: i32 = 1;
prn(x);
}
Would it be possible to use a newtype like below to let me make fn prn
generic and not have to specify all the traits on each impl?
pub struct MyData<T>(T)
where
T: std::fmt::Debug + Copy + Clone + std::ops::Add<Output = T>;
My failed attempt below:
// WRONG - won't compile - is there syntax for newtype as type param?
fn prnt<MyData<T>>(arg: T) {
println!("{:?}", arg);
}
fn main() {
let x: i32 = 1;
prnt(x);
}
英文:
I am trying to avoid specifying multiple traits on each use of generic type T. Can I use the newtype idiom to specify bounds once? This works but I'll have the where ...
on each function.
fn prn<T>(arg: T)
where
T: std::fmt::Debug + Copy,
{
println!("{:?}", arg);
}
fn main() {
let x: i32 = 1;
prn(x);
}
Would it be possible to use a newtype like below to let me make fn prn
generic and not have to specify all the traits on each impl?
pub struct MyData<T>(T)
where
T: std::fmt::Debug + Copy + Clone + std::ops::Add<Output = T>;
My failed attempt below:
// WRONG - won't compile - is there syntax for newtype as type param?
fn prnt<MyData<T>>(arg: T) {
println!("{:?}", arg);
}
fn main() {
let x: i32 = 1;
prnt(x);
}
答案1
得分: 2
不。newtype 是一种具体类型,不是任何类型的约束。
您可以使用特质继承和通用实现来"捆绑"特质:
trait Thing: std::fmt::Debug + Copy + Clone {}
impl<T> Thing for T where T: std::fmt::Debug + Copy + Clone {}
fn foo<T: Thing>(v: T) {
println!("{v:?}");
}
fn main() {
foo("bar");
foo(1);
foo(false);
}
虽然我认为您不能使用宏来声明通用约束(这将是一种替代方法),但如果您需要许多这样的特质,您可以使用宏一次性声明特质和通用实现:https://stackoverflow.com/a/57848887/8182118
英文:
> Would it be possible to use a newtype like below
No. A newtype is a concrete type, it's not any sort of constraint.
You can use trait inheritance and blanket implementations to "bundle" traits:
trait Thing: std::fmt::Debug + Copy + Clone {}
impl <T>Thing for T where T: std::fmt::Debug + Copy + Clone {}
fn foo<T: Thing>(v: T) {
println!("{v:?}");
}
fn main() {
foo("bar");
foo(1);
foo(false);
}
And while I don't think you can use macros to declare generic constraints (which would be an alternative) if you need many such traits you can use macros to declare the traits & blanket impls in one shot: https://stackoverflow.com/a/57848887/8182118
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论