簡體   English   中英

簡單的 rust 通用/模板添加功能

[英]simple rust generic/template add function

所以我只是在學習 rust - 我已經設置了工具並讓它們在結構上工作,交叉編譯,鏈接庫等等......我有 C++ 背景)。 所以在 C++ 談話中我想這樣做:

C++

template<typename A, typename B>
auto add(A a, B b)
{
    return a + b;
}

int main() {
    std::cout << "add int int:    " << add(1, 2) << std::endl;
    std::cout << "add int double: " << add(1, 2.3f) << std::endl;
    std::cout << "add int float:  " << add(1, 2.3) << std::endl;
    std::cout << "add char int:   " << add('g', 2.3) << std::endl;
    std::cout << "add str str:    " << add(std::string("bob"), std::string("fred")) << std::endl;
}

輸出:

add int int:    3
add int double: 3.3
add int float:  3.3
add char int:   105.3
add str str:    bobfred

這增加了“事物”。 如果您嘗試添加兩個未使用正確操作數實現正確+運算符的內容,您將收到編譯錯誤(如添加字符串和整數) - 非常簡單。

現在生銹(我完全沒有掌握它。

普通添加功能

pub fn add(a: u64, b: u64) -> u64 {
    return a + b;
}

到目前為止還好。

嘗試 1 將這個模板化我通過聽取錯誤並使用建議的更改(使用std::ops::Add<Output = T>我有點理解它,但我真的不知道為什么我必須指定這個。

pub fn add<T: std::ops::Add<Output = T>>(a: T, b: T) -> T
{
    return a + b;
}


println!("add int int:   {}", add(1, 2));    // ok
println!("add int float: {}", add(1, 2.3));  // fails to compile

這是意料之中的,因為我只告訴它一種類型......所以現在嘗試兩種類型 A、B - 但這是我迷路的地方:

pub fn add<A: std::ops::Add<Output = A>, B: std::ops::Add>(a: A, b: B) -> A
{
    return a + b;
}

我得到的錯誤是:

error[E0308]: mismatched types
  --> utils/src/lib.rs:19:16
   |
17 | pub fn add<A: std::ops::Add<Output = A>, B: std::ops::Add>(a: A, b: B) -> A
   |            - expected type parameter     - found type parameter
18 | {
19 |     return a + b;
   |                ^ expected type parameter `A`, found type parameter `B`
   |
   = note: expected type parameter `A`
              found type parameter `B`
   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

所以現在我完全迷失了。 首先,我似乎必須指定一個返回類型 - 但我希望為我推斷出它。 我怎么做? 其余的錯誤可能都是由於返回類型為A - 但我似乎必須指定一些東西......這里的任何幫助都會很棒! - 如果可能的話,我想存檔與上述 c++ 模板相同的基本功能

首先,你最好先參考std::ops::Add的文檔。 您已經設置了一個type Output ,但您也可以設置一個模板參數Rhs 所以你可以試試:

pub fn add_to_rhs<A, B>(a: A, b: B) -> B
  where A: std::ops::Add<B, Output = B>
{
    return a + b;
}

在那里你聲明 LHS 值應該與 RHS 值相加,最后產生一種 RHS 值。 但這仍然無法按您預期的那樣工作

println!("add int float: {}", add_to_rhs(1, 2.3)); 
// fails to compile, no implementation for `{integer} + {float}`

這是合理的,因為弱類型不適合 Rust,因為它容易出現邏輯錯誤。 什么是可能的解決方法? 實際上類似於您在非通用程序中所做的事情——您將顯式轉換其中一個值:

pub fn add_to_rhs<A, B>(a: A, b: B) -> B
where A: Into<B>, B: std::ops::Add<Output = B>
{
    return a.into() + b;
}

這不能實現與 C++ SFINAE 相同的靈活性(記住,沒有弱類型),因為為了添加任何值,您需要制作兩個版本的函數; 我展示了一個變體,其中 LHS 值被轉換並添加到 RHS 類型,但您也需要相反的方式。

而且由於我們在 Rust 中沒有重載,這變得更不方便,你必須調用不同的函數並記住這一點。

編輯:我玩了一點,並設法為不同類型的混合使用一個函數,但使用它迫使您每次都指定一個返回類型

struct Adder<T>(std::marker::PhantomData<T>);
impl<T> Adder<T> {
    fn add<A, B>(a: A, b: B) -> T
      where T: std::ops::Add<Output = T>, A: Into<T>, B: Into<T> {
        return a.into() + b.into();
    }
}


println!("add int int:   {}", Adder::<i32>::add(1, 2));
println!("add int float: {}", Adder::<f64>::add(1, 2.3)); 
println!("add float int: {}", Adder::<f64>::add(2.3, 1));

struct 的目的是將add的模板參數(可以完全推導出)與生成的模板參數(您需要指定,否則返回類型不明確)分開

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM