5章を読んでいこう。
- inline
- ここにinlineの説明があるのは唐突感があるなあ・・・
- プリミティブ型
stringのインデックスとスライスはこんな感じ。...
はないみたい。
> let str = "1234567890";; val str: string = "1234567890" > str.[3];; val it: char = '4' > str.[5..8];; val it: string = "6789" > str.[5..];; val it: string = "67890" > str.[..8];; val it: string = "123456789" > str.[5...8];; str.[5...8];; --------^ /Users/tambara/study/fs_study/stdin(10,9): error FS0010: 予期しない シンボル '.' です 式内。']' または他のトークンを指定してください。 > str.[*];; val it: string = "1234567890"
- 型変換
- 型名の演算子があるのでそれを使う
- 文字/文字列から数値へも変換可能(float "2" -> 2.0)
- オーバーフロー
- 普通はオーバーフローしない。intの範囲を超えたら循環する
- オーバーフローしたら例外にするには
open Checked
を実行しておく- ただし、型変換ではやっぱり循環する・・・と本には書いてあるけど、やってみるとしない。動作変わったっぽい
> let i = 2147483647;; val i: int = 2147483647 > i+1;; // オーバーフローすると循環する val it: int = -2147483648 > let i64 = int64 i;; val i64: int64 = 2147483647L > i64+1;; // int64とintは足せない i64+1;; ----^ /Users/tambara/study/fs_study/stdin(4,5): error FS0001: 型 'int' は型 'int64' と一致しません > i64+1L;; // int64なのでオーバーフローしない val it: int64 = 2147483648L > int(i64+1L);; // これをintに戻すと循環する val it: int = -2147483648 > open Checked;; // おまじない > i+1;; // オーバーフローしたら例外 System.OverflowException: Arithmetic operation resulted in an overflow. at <StartupCode$FSI_0011>.$FSI_0011.main@() エラーのため停止しました > int(i64+1L);; // 型変換でオーバーフローしても例外 System.OverflowException: Arithmetic operation resulted in an overflow. at <StartupCode$FSI_0010>.$FSI_0010.main@() エラーのため停止しました
- nanとinfinity
- これはfloatの値。float32にはnanfとinfinityfがある
- nanかどうかのチェックは
System.Double.IsNaN()
を使う
- printfがある。printfなので可変長引数。F#で可変長引数をどうやって扱うかというと、コンパイラが特別扱いするからなのでとりあえずは気にしなくてよいらしい。printfはいつも謎
- 演算子オーバーロードがある
たとえば、(+)だと、とりあえずでintにされてしまう(笑)
> let 足し算 x y = x + y;; val 足し算: x: int -> y: int -> int
ここで、例えば戻り値の型を与えると、引数の型も決まる
> let 文字列連結 x y : string = x + y;; val 文字列連結: x: string -> y: string -> string
inlineを指定すると、展開された時点で決まることになるんだそうな。
> let inline add x y = x + y;; val inline add: x: ^a -> y: ^b -> ^c when ( ^a or ^b) : (static member (+) : ^a * ^b -> ^c)
いったん、今日はここまで。また5章の続きからやる。