Prashant N Mhatreさんによる新しいプログラミング言語を学ぶための15のエクササイズをRustでやっていますがその過程で気づいたことを書いています。
一応、Rustで新しいプログラミング言語を身につける15のエクササイズシリーズの一つです。
今回のテーマ
swapping two variables,
この課題……失敗しました! とりあえずコード
fn main() {
let a: i64 = 50;
let b: i64 = 15;
let (a, b) = swap0(a, b);
println!("a: {}, b: {}", a, b);
}
// 一次変数を用意する方法。大体どんな型でも使える。
fn swap0(a: i64, b: i64) -> (i64, i64) {
return (b, a)
}
なんの問題もなくSwapされたように見えます……が問題ありです。
曲者なのが、let (a, b)の部分で、ここでaとbを再定義しています。
例えば、以下のコード
fn main() {
let c: i64 = 50;
let d: i64 = 15;
let (c, d) = return_i32(c, d);
println!("c: {}, d: {}", c, d);
}
fn return_i32(_: i64, _: i64) -> (i32, i32) {
let int1: i32 = 67;
let int2: i32 = 22;
return (int1, int2)
}
このコードはちゃんとコンパイルを通って動きます。はじめcとdはi64型だったのに、最後はi32型になっています。
そこで気になって書いてみたのが下のコードです。
再定義の実験
fn main() {
let a: i64 = 300;
println!("{}", a);
let a: u16 = 20;
println!("{}", a);
}
このコード、ちゃんとコンパイル通って動作します。
今まで私が触ってきた言語からすると不思議なのですが、Rustは同じ名前の変数の再定義ができるようです。
私が今まで触ってきた言語(go)からすると不思議な仕様だったのでなかなか興味深いです。型に対してなんでもありの動的言語は除くとして、このあたりの処理ってどう言うのが主流なんでしょうか?
goで再定義しようとすると
package main
import "fmt"
func main() {
var a int64 = 30
fmt.Println(a)
var a string = "Hello, World!"
fmt.Println(a)
}
ちなみにgoの場合はエラーが起こります。
まとめ
- Rustでは変数を同名で再定義できる。
- Goではできないけど他がどうなってるかはよくわからない。
課題の方は、別のタプルを用意して、逐一変数c, dに代入すれば問題はないのですが、なんだか釈然としません。