Edited at

[Swift] 乱数取得でキャストにハマったのでメモ(arc4random)

More than 5 years have passed since last update.


問題

乱数取得で剰余(%)を使用したときにハマったのでメモを残します。

func getRandomNumber(cnt:Int) -> Int{

var result:Int
result = arc4random() % cnt
return result
}

arc4randomを使っている行で以下のエラーが発生します。

Could not find an overload for '%' that accepts the supplied arguments

オーバーロードが見つからない?なんでしょう。。

%でエラーになっているので、剰余に問題がありそう、というところまでは解ります。


失敗: キャストしてみた

func getRandomNumber(cnt:Int) -> Int{

var result:Int
result = Int(arc4random() % cnt)
return result
}

剰余(余りを算出)しようとしたときに小数点を利用する型に変換されるのかなと思い、

キャストしてみましたが以下エラーが発生。

Could not find an overload for 'Init' that accepts the supplied arguments

今度は Initです。どこかの初期化でエラーになっているんでしょうが詳細解りません。


気付き


func getRandomNumber(cnt:Int) -> Int{
var result:Int
result = Int(arc4random() % 20)
return result
}

除数に数値をベタ書きするとエラーになりません。

どうやら除数の型が問題のようです。


失敗: 除数の型を浮動小数点型にしてみる

func getRandomNumber(cnt:Int) -> Int{

var result:Int
result = Int(arc4random() % Double(cnt))
return result
}

エラーが解消しません。。。


正解:符号なし整数

func getRandomNumber(cnt:Int) -> Int{

var result:Int
result = Int(arc4random() % UInt32(cnt))
return result
}

なんとUInt32で解消。

剰余に使う除数は、符号なし整数を使うようです。


感想

Swiftの型推論に注目が集まり、柔軟なイメージでしたが、

今回、堅い一面を見ました。

2014.07.07 追記

arc4randomの戻り値がUInt32だったのでそれに合わせる必要がありました。

ただ、関数の戻り値確認方法が解らず。

いちおう、一応以下で確認できました。


var hoge = arc4random
if hoge is UInt32 {

}

if文のところで以下のエラーが出ます。

'is' hoge is always true

@Ushio@githubさん ありがとうございました。