67524


とあるネットワーク系プログラムをRustで書いています。そこで`String`型が何故か`usize`として認識されてしまっているので質問させていただきます。かなりのコード量な上、検索に引っかかると厄介な個人的事情もありますので、必要な部分のみを掲載させていただきます。予めご了承ください。

## 問題の箇所

[code]

        let &ip; let host; let parse_ip; let perse_host;
        let ipx = &ip;
    
        if cli.value_of("ipaddress").is_none() && cli.value_of("hostname").is_none() {
            println!("{}", HELP);
            std::process::exit(1);
        } else if cli.value_of("ipaddress").is_some() || cli.value_of("hostname").is_none() {
            ip = String::from(cli.value_of("ipaddress").unwrap());  
            parse_ip = ip.parse::<IpAddr>().unwrap();
    
        } else {     
            host = cli.value_of("hostname").unwrap();
            perse_host = || {
                let hostname: Vec<std::net::IpAddr> = lookup_host(host).unwrap();
                let host_to_ip = hostname[0].clone();
                return host_to_ip;
            };
        }
    
[/code]

このように条件付きで、入力ホストとIPをそれぞれパース・初期化を行っています、この時点て後述する`let
ip`は[E0614](https://doc.rust-lang.org/error-index.html)に引っかかったので、例に習い`let ipx
= &ip;`としています。

[code]

        let mut network_node;
    
        if *ipx.len() <= 3 {
            eprintln!("\x1b[31m[-]\x1b[m CAN NOT PARSE YOUR INPUT INTO IpAddr!");
            std::process::exit(1);
        } else {
            network_node = parse_ip;
        }
            
        if perse_host().is_ipv4() {
            eprintln!("\x1b[31m[-]\x1b[m CAN NOT PARSE YOUR INPUT INTO HOST!");
            std::process::exit(1);
        } else { 
            network_node = perse_host();
        }
    
[/code]

次がコードの制御部です。先の`ip`の参照を`ipx`に渡したものを、参照外しで逆参照しています。しかしここで、

`type `usize` cannot be dereferenced`

と出てしまいます。自分の認識ではString型はコンパイル時にサイズが決定する筈なので、通常ではチェックは通るはずなのですが、現時点まで未解決のままです。

これを解決するにはどのような手段を取ればよいのでしょうか？

## 環境

[code]

    active toolchain
    ----------------
    
    nightly-x86_64-unknown-linux-gnu (default)
    rustc 1.45.0-nightly (56daaf669 2020-06-03)
    
[/code]


CC BY-SA 4.0
2020-06-11T00:19:46.737
67518
2020-06-11T02:46:19.070
2020-06-17T08:14:45.997
-1
30493
question
rust
RustのStringは「usize」なのか？


問題なのは `*ipx.len() <= 3` の部分ですね。  
`*ipx.len()` は、 `*(ipx.len())` と解釈されます。 `ipx.len()` の返り値は `usize`
なので、それを参照外ししようとして、エラーになっています。  
また、Rustでは `recv.method()` と呼んだ際は辻褄が合うように `*` や `&` が裏で付与されるので、レシーバに `&` や `*`
をつけり必要性は基本的にはありません （参考： [->演算子はどこに行ったの？](https://doc.rust-jp.rs/book/second-
edition/ch05-03-method-
syntax.html#a-%E6%BC%94%E7%AE%97%E5%AD%90%E3%81%AF%E3%81%A9%E3%81%93%E3%81%AB%E8%A1%8C%E3%81%A3%E3%81%9F%E3%81%AE)）。

なので `ipx.len() <= 3` と書き換えたらコンパイルが通らないでしょうか。


CC BY-SA 4.0
2020-06-11T00:31:25.267
67519
2020-06-11T00:31:25.267
22816
67518
answer


>
> ご指南通り、アスタリスクを外してみたところ、なにやら「初期化が必要」とのエラーが発生したのですが、これはどう解決すれば良いのでしょうか...nullの代わりにNoneと()を入れてみましたが解決できませんでした...
> ``borrow of possibly-uninitialized variable: ip use of possibly-
> uninitialized `ip```

コードを省略されているため、意図がわかりづらい部分があるのですが、

[code]

    let &ip;
    let ipx = &ip;
    
[/code]

は本来はip変数に何かString型の値を入れるコード (仮に `get_ip()` とします) が存在するという仮定で回答します。

ipがString型なのであればString型の値で初期化する必要があります。

変数宣言時に値を入れる場合。

[code]

    let ip: String = get_ip();
    println!("{}", ip);
    
[/code]

値の取得にあたって条件分岐などがあり、まず空文字で初期化する場合。

[code]

    let mut ip: String = "".to_string()
    if is_something() {
      ip = get_ip();
    }
    println!("{}", ip);
    
[/code]

Noneで初期化する場合はOption型にする必要があります。

[code]

    let mut ip: Option<String> = None;
    if is_something() {
      ip = Some(get_ip());
    }
    println!("{}", ip.unwrap());
    
[/code]


CC BY-SA 4.0
2020-06-11T02:46:19.070
67524
2020-06-11T02:46:19.070
31392
67518
answer