# Rust演習
## プロジェクト作成
プロジェクト作成
```bash
cargo new myproj
cd myproj
```
ビルド
```bash
cargo build
```
実行
```bash
cargo run
# hello world
```
## 変数と可変性
`let var`で定義した変数varは変更することができない。`let mut var`
```rust
//コンパイルエラー
fn main() {
let x = 5;
println!("The value of x is: {}", x);
x = 6; //xは変更できない
println!("The value of x is: {}", x);
}
```
上のコードはエラーが出るので、以下のように書き換える必要がある。
```rust
fn main() {
let mut x = 5;
println!("The value of x is: {}", x);
x = 6; //xは変更できない
println!("The value of x is: {}", x);
}
```
### 戻り値の書き方
```rust
fn main() {
println!("{}",add1(100,200));
println!("{}",add2(150,250));
}
fn add1(x:i32, y:i32) -> i32{
let ans = x + y;
return ans;
}
fn add2(x:i32,y:i32) -> i32{
let ans = x + y;
ans
}
```
## 所有権
### 変数のスコープ
```rust
//コンパイルエラー
fn main() {
{
let x = 5;
let s = String::from("hello");
}
println!("{}",x);
println!("{}",s);
}
```
変数s(が指し示すデータ)は中括弧の中のみで有効なので、以下のように書き換える。
```rust
fn main() {
{
let x = 5;
let s = String::from("hello");
println!("{}",x);
println!("{}",s);
}
}
```
### 変数の束縛と所有権の移動
```rust
fn main(){
let x = 5;
let y = x;
println!("{}",x);
}
```
```rust
//コンパイルエラー
fn main(){
let s1 = String::from("hello");
let s2 = s1;//"hello"の所有権がs1からs2に移動
println!("{}",s1);
}
```
### 関数とスコープ
```rust
//コンパイルエラー
fn main() {
let s1 = String::from("hello");
let len1 = calculate_length(s1);
let len2 = calculate_length(s1);
}
fn calculate_length(s: String) -> usize {
let length = s.len(); // len()メソッドは、Stringの長さを返します
length
}
```
### 一つの解決法(所有権を、戻り値で渡してもどす。)
```rust
fn main() {
let s1 = String::from("hello");
let (s2, len) = calculate_length(s1);
//'{}'の長さは、{}です
println!("The length of '{}' is {}.", s2, len);
}
fn calculate_length(s: String) -> (String, usize) {
let length = s.len(); // len()メソッドは、Stringの長さを返します
(s, length)
}
```
面倒なので、所有権を移動させないままでヒープデータを扱いたい。
## 参照
```rust
fn main() {
let s1 = String::from("hello");
let len1 = calculate_length(&s1);
let len2 = calculate_length(&s1);
}
fn calculate_length(s: &String) -> usize {
let length = s.len(); // len()メソッドは、Stringの長さを返します
length
}
```