LoginSignup
6
8

More than 3 years have passed since last update.

宣言文と関数定義とlet式(束縛とミュータビリティ)(Rustの基本構文-1-)

Last updated at Posted at 2019-11-20

はじめに

Rustの基本的な文法をまとめてみた。

目的

Rustにおける基本的な構文の理解をする。
それらを活用したコードの作成。

ソースコード(うるう年と平年)

from URL: https://github.com/ghmagazine/rustbook/blob/master/ch06/leap-year/src/main.rs
このコードが基本的なことがいろいろあるので、使用していく。これを紐解くことで理解を深めていく。

// 入力された年がうるう年かどうかを判断するプログラム

// `std::io` 名前空間を `io` としてインポート
use std::io;
// `std::io::Write` トレイトを使う
use std::io::Write;

// エントリポイントとなる関数
fn main() {
    let mut year = String::new();
    print!("Please input a year to check if it is a leap year: ");
    io::stdout().flush().unwrap();
    io::stdin().read_line(&mut year).unwrap();
    let year = year.trim().parse::<u32>().unwrap();

    if is_leap_year(year) {
        println!("{} is a leap year!", year);
    } else {
        println!("{} is not a leap year.", year);
    }
}

// うるう年の場合は `true` 、平年の場合は `false` を返す関数
fn is_leap_year(year: u32) -> bool {
    year % 4 == 0 && !(year % 100 == 0 && year % 400 != 0)
}

コメント

どの言語においても、コードの説明をするために日本人であれば日本語で何をしているかを説明する。
"//[文章]"または、"/*[文章]*/"を付けることによってコードに影響の与えないように自由に記述できる。([文章]:任意の文)

//行コメント
//行コメントは1行のみ。
/*ブロックコメント*/
/*ブロックコメントは
複数行でも
書くことができる。*/

上記のコメントの書き方は「普通コメント」で一般的なコメントの書き方である。
どちらかというと、行コメントの方が好ましいとされている。

その他に、「ドキュメンテーションコメント」と呼ばれるものがある。それぞれの例を次に示す。

///アイテムドキュメント
//!クレートや、モジュール(ファイルやディレクトリに切り出されたもの)

/**[文章]*//*![文章]*/は非推奨とされている。

宣言文

2つある。
・アイテム宣言
 ex) use宣言、関数定義
・let文
 変数の導入

関数定義

基本的に関数は下のように示す。

fn 関数名([引数リスト])[-> 戻り値の型]{
    [本体部分]
}

//シグネチャ
fn 関数名([引数リスト])[-> 戻り値の型]

fnは関数定義宣言。(functionから由来だと思う…)
[引数リスト]については、編集対象ファイルの一覧を指す。この時の記述の仕方は[名前: 型]で書く。
上記にあるようにfn 関数名([引数リスト])[-> 戻り値の型]の部分は"シグネチャと"呼ぶ。さらに、戻り値の型は、ユニットを返す時は省略できる。

「うるう年と平年」のソースコードには、

fn main(){
}

fn is_leap_year(year: u32) -> bool{
}

この二つの関数で、構成されている。

let文(基本構文、束縛とミュータビリティの実行確認)

基本構造は以下のようになっている。

//基本構文
let パターン[: ] [=初期化式];

//「うるう年と平年」上では
let mut year = String::new();

let式は"束縛"が重要となってくる。「変数を値に束縛する」という表現がある。これは、変数と数値を結び付けることである。

例を引用してくる。(from 実践Rust入門 言語仕様から開発手法まで P.224,225-例1,2)

//1.型の省略
let date_string = "2019-11-20";
//2.型の明示省略
let pi: f64 = 3.14;
//3.初期化の省略
let not_initialized;

//4.文字列への束縛
let mut mutable_string = String::from("String");
//5.別の文字列への束縛
mutable_string = String::from("Hello");
//6.文字列の変更
mutable_string.push_str(", world!");
//7.エラー”異なる型の値に束縛の上書きはできない。
mutable_string = 2019;

vscode上でこれを4から実行してみる。

fn main(){
    //4.文字列への束縛
    let mut mutable_string = String::from("String");

    println!("{}", mutable_string);
}

ターミナル表示

warning: variable does not need to be mutable
 --> let_sentense.rs:3:9
  |
3 |     let mut mutable_string = String::from("String");
  |         ----^^^^^^^^^^^^^^
  |         |
  |         help: remove this `mut`
  |
  = note: `#[warn(unused_mut)]` on by default

実行はされるが、Warningが出てくる。この場合、mutを取り除くことによって、正常に実行できる。

次に、4のあとに5を行ってみる。

fn main(){
    //4.文字列への束縛
    let mut mutable_string = String::from("String");
    //5.別の文字列への束縛
    mutable_string = String::from("Hello");

    println!("{}", mutable_string);
}

これを実行してみる。

warning: unused variable: `mutable_string`
 --> let_sentense.rs:3:13
  |
3 |     let mut mutable_string = String::from("String");
  |             ^^^^^^^^^^^^^^ help: consider prefixing with an underscore: `_mutable_string`
  |
  = note: `#[warn(unused_variables)]` on by default

warning: variable does not need to be mutable
 --> let_sentense.rs:3:9
  |
3 |     let mut mutable_string = String::from("String");
  |         ----^^^^^^^^^^^^^^
  |         |
  |         help: remove this `mut`
  |
  = note: `#[warn(unused_mut)]` on by default

実行はされて、"Hello"という表示はできるが、二つのWarningがでてくる。
・help: consider prefixing with an underscore: _mutable_string
・help: remove this mut
と書かれているので、その二つに沿って、以下のようにコードを直して、実行すると正常に実行できた。

fn main(){
    //4.文字列への束縛
    let _mutable_string = String::from("String");
    //5.別の文字列への束縛
    let mutable_string = String::from("Hello");

    println!("{}", mutable_string);
}

次に文字列の変更(6)をやって見る。上記のようにではなく、警告文もなく、実行できるコードを以下のようなる。

fn main(){
    //4.文字列への束縛
    let _mutable_string = String::from("String");
    //5.別の文字列への束縛
    let mut mutable_string = String::from("Hello");
    //6.文字列の変更
    mutable_string.push_str(", world!");
    println!("{}", mutable_string);
}

これに対して、異なる型の文字列を束縛しようとしてみる。

fn main(){
    //4.文字列への束縛
    let _mutable_string = String::from("String");
    //5.別の文字列への束縛
    let mut mutable_string = String::from("Hello");
    //6.文字列の変更
    mutable_string.push_str(", world!");
    //7.エラー”異なる型の値に束縛の上書きはできない。
    mutable_string = 2019;
    println!("{}", mutable_string);
}

これを実行すると以下のようなErrorが発生する。

error[E0308]: mismatched types
 --> let_sentense.rs:9:22
  |
9 |     mutable_string = 2019;
  |                      ^^^^
  |                      |
  |                      expected struct `std::string::String`, found integer
  |                      help: try using a conversion method: `2019.to_string()`
  |
  = note: expected type `std::string::String`
             found type `{integer}`

error: aborting due to previous error

よって、別型の文字列への束縛ができないことがわかる。sunawati
let文における変数はイミュータブルだとわかった。

さいごに

Rustにおいてある程度理解を深めた状態でコードの作成を行い、実行時のエラーについては他言語より分かりやすく、また推測まで出してくれるために非常に直しやすい。基本構文についてはまだ続編を書く予定。

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8