66821


### プロローグ

現在「HACKING:美しき策謀」という書籍を読んでからというもの、型安全なRustでも「パニックが起こるのはまずいのではないか？」と思い、想定されていない使われ方をしても、エラーメッセージを出力し、正常終了と言う形で結果を返したくなり、以前組んだプログラムを改良しています。

### 問題

[code]

    fn t_or_f(x1: i64, ps1: &Vec<i64>) -> bool {
        for p1 in ps1 {                   
            if p1 * p1 > x1 {                                      
                 break;                                            
                } else if x1 % p1 == 0 {                               
                    false;                                     
            }                                                  
        }                                                          
        true                                                                         
    }                                                                                
    
    fn prime(n1: i64) {                                                               
        let mut ps2 = vec![2];                                                        
        let mut x2 = 3;    
    
        if n1 <= 1 {
            println!("NOT FOWND THIS {} FIELD",n1);        
        } else {
            while x2 <= n1 {                                                            
                if t_or_f(x2, &ps2) {                                                   
                   ps2.push(x2);                                                       
                }                                                                       
                x2 += 2;                                                         
            }
            println!("{:?}", &ps2);
        }                                                  
    }                                                                                   
    
    fn main() {                       
        trait Trans {
            fn from(num1: String) -> i64;
        }
    
        impl Trans for i64 {
            fn from(num1: String) -> i64 {
                let sumx;
                for ix in num1.chars() {
                // ここで let array[] = ix という処理を掛けて配列にcharを格納していき、それぞれを結合し i64 整数にトランスさせたい（もっといい方法があると思いますが）。
                }
                return sumx;
            }
        }
    
        let arg:　String = std::env::args().nth(1);
    
        if arg.len() == 1 {  
            println!("NO INSET VALUES");
        } else {          
            let p: i64 = i64::Trans::from(arg);                                       
            prime(p);     
        }                                                                  
    }
    
[/code]

ここに上のようなコードがあったとします、単刀直入に言って上記のような配列に格納された細切れの`char`を格納した配列を、`i64`整数として処理するには、どのような手段を取れば良いのでしょうか？`i64`には`String`に対する`from()`は提供されていなかったので、自分で`from`関数を書くことにしました（†備考:非常に遠回りな気がしますが、自分も知識としてトレイトを知っているだけなので、実践したのは初。なので、これが適切かどうかすらわからない状態）。

また、自作トレイとを`i64`に実装するという大掛かりな手段を用いなくても片付くのであれば、僭越ながら、その手法を掲載・解説していただければ、嬉しく思います。


CC BY-SA 4.0
2020-05-20T12:08:05.573
66818
2020-05-20T13:24:06.550
30493
question
rust
Rustで配列へ細切れに格納されたchar（数字）をi64型整数として返す方法


> 上記のような配列に格納された細切れの`char`を格納した配列を、`i64`整数として処理するには、どのような手段を取れば良いのでしょうか？

`String`を`i64`整数に変換したいという理解で合っていますか？
それでしたら`str`型の`parse()`メソッドが使えます（[ドキュメント](https://doc.rust-
lang.org/std/primitive.str.html#method.parse)）

`parse()`メソッドは`Result`型の値を返します。

  * `"10"` → `Ok(10)`
  * `"-1"` → `Ok(-1)`
  * `"x"` -> `Err(std::num::ParseIntError)`

また、エラー処理ですが、`Result`型と`?`演算子を使うと以下のようにすっきりと書けます。

[code]

    fn t_or_f(x1: i64, ps1: &Vec<i64>) -> bool {
        // 元のコードから変更なし
    }
    
    // 戻り値型をResultに変更する
    fn prime(n1: i64) -> Result<(), Box<dyn std::error::Error>> {
        let mut ps2 = vec![2];
        let mut x2 = 3;
    
        if n1 <= 1 {
            // エラーのときはErrを返す
            Err(format!("NOT FOUND THIS {} FIELD", n1).into())
        } else {
            while x2 <= n1 {
                if t_or_f(x2, &ps2) {
                    ps2.push(x2);
                }
                x2 += 2;
            }
            println!("{:?}", &ps2);
            // 処理に成功したときはOkを返す
            Ok(())
        }
    }
    
    // main()の処理を別の関数に切り出し、Resultを返すようにする
    fn find_prime() -> Result<(), Box<dyn std::error::Error>> {
        let arg = std::env::args()
            .nth(1)
            // ・ok_or_else()でOption型からResult型へ変換する
            // ・?演算子はOkならunwrapし、Errなら早期returnする
            .ok_or_else(|| "NO INSET VALUES".to_string())?;
        let p = arg.parse()?;
        prime(p)
    }
    
    fn main() {
        // find_prime()を呼び、Errが返ったら、その内容を表示する
        if let Err(e) = find_prime() {
            eprintln!("Error: {}", e);
        }
    }
    
[/code]

**実行結果**

[code]

    $ cargo run -- 10
    [2, 3, 5, 7, 9]
    
    $ cargo run
    Error: NO INSET VALUES
    
    $ cargo run -- -1
    Error: NOT FOUND THIS -1 FIELD
    
    $ cargo run -- x 
    Error: invalid digit found in string
    
[/code]

エラー処理について詳しくは公式ドキュメントの [このあたり](https://doc.rust-jp.rs/book/second-
edition/ch09-02-recoverable-errors-with-result.html) を参考にしてください。


CC BY-SA 4.0
2020-05-20T13:01:00.303
66821
2020-05-20T13:24:06.550
2020-05-20T13:24:06.550
14101
14101
66818
answer