開発メモ

開発関係のメモをいろいろと。たぶん。

The Swift Programming Languageのメモ(その5)

はじめに

これは、『The Swift Programming Language』を読んだ時の個人的なメモです。なので、引用はすべて『The Swift Programming Language』から。

iTunes - ブック - Apple Inc.「The Swift Programming Language」
https://itunes.apple.com/jp/book/swift-programming-language/id881256329?mt=11

その4はこちら。

The Swift Programming Languageのメモ(その4) - 開発メモ
http://seeku.hateblo.jp/entry/2014/06/08/195708


Control Flow

  • SwiftにはCによく似た制御文があるよ
    Cより便利なものもあるよ。Swiftのswitchは強力だよ。

For-In

  • 取り出した値は自動で定数(let)になるよ
  • 値が要らない時は『_』で捨てることが出来るよ
let base = 3
let power = 10
var answer = 1
for _ in 1...power {
    answer *= base
}
println("\(base) to the power of \(power) is \(answer)")
// prints "3 to the power of 10 is 59049

Switch

  • switch文には考えられるすべてのパターンが必要だよ
    つまり、大抵の場合、一番下にdefaultが必要になるよ。

No Implicit Fallthrough

  • あるcaseから次のcaseに、勝手に移ることはないよ
    『fallthrough』を使えば、明示的に移ることは出来るよ。

Range Matching

  • caseには範囲を指定することも出来るよ

Tuples

  • caseにはタプルを指定することも出来るよ
  • この場合『_』ですべての値にマッチさせることが出来るよ
  • 複数のcaseに当てはまる場合、最初にマッチしたcaseが使われるよ

Value Bindings

  • caseでマッチした値を変数に取り出すことも出来るよ
let anotherPoint = (2, 0)
switch anotherPoint {
case (let x, 0):
    println("on the x-axis with an x value of \(x)")
case (0, let y):
    println("on the y-axis with a y value of \(y)")
case let (x, y):
    println("somewhere else at (\(x), \(y))")
}
// prints "on the x-axis with an x value of 2

Where

  • caseには『where』で追加の条件を付けられるよ
let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:
    println("(\(x), \(y)) is on the line x == y")
case let (x, y) where x == -y:
    println("(\(x), \(y)) is on the line x == -y")
case let (x, y):
    println("(\(x), \(y)) is just some arbitrary point")
}
// prints "(1, -1) is on the line x == -y

メモ: ここまでやるなら、ifを重ねたほうが楽では?

Break in a Switch Statement

  • caseの中がコメントだけだとコンパイル時エラーになるよ
    この場合、caseの中にbreakだけ書いておけばいいよ。

Labeled Statements

  • ループ文やswitch文にはラベルを付けることが出来るよ
    breakとcontinueの飛び先をlabelで指定することが出来るよ。

  • ラベルは同じ行で文の前に書くよ
    具体的にはこんな感じになるよ。

label name: while condition {
    statements
}

Functions

  • 関数の引数には、デフォルト値とか値の参照(inout)とかも使えるよ
  • 関数を関数の引数とか戻り値に使うことも出来るよ

Functions Without Parameters

  • 引数なしの関数はこんな感じになるよ
    関数名の後ろの『()』も必要だよ。
func sayHelloWorld() -> String {
    return "hello, world"
}
println(sayHelloWorld())
// prints "hello, world

Functions Without Return Values

  • 戻り値がない場合、『->』以降を省略できるよ
func sayGoodbye(personName: String) {
    println("Goodbye, \(personName)!")
}
sayGoodbye("Dave")
// prints "Goodbye, Dave!
  • 厳密に言うと、戻り値が指定されない場合、Void型が戻り値になるよ
    Voidは中身が0のタプルと同じ意味だよ。

Functions with Multiple Return Values

  • タプルを使って、複数の値をまとめて返すことが出来るよ
return (vowels, consonants, others)
  • こんな感じで取り出せるよ
let total = count("some arbitrary string!")
println("\(total.vowels) vowels and \(total.consonants) consonants")
// prints "6 vowels and 13 consonants

メモ: 取り出しに使うラベルは関数の戻り値で指定されたものになる

Function Parameter Names

  • 関数の引数名は、関数の中でだけ使われるよ

External Parameter Names

  • 関数を呼び出すときに使う引数名を設定することも出来るよ
    内部で使う引数名の前に、スペースで区切って書くよ。
func someFunction(externalParameterName localParameterName: Int) {
    // function body goes here, and can use localParameterName
    // to refer to the argument value for that parameter
}
  • 外部引数名が設定されると、関数を呼び出すときに絶対に必要になるよ

メモ: この仕様、必要なの?

Shorthand External Parameter Names

  • 引数名の前に『#』を書くと、内部と外部両方の引数名になるよ
func containsCharacter(#string: String, #characterToFind: Character) -> Bool {
    for character in string {
        if character == characterToFind {
            return true
        }
    }
    return false
}

Default Parameter Values

  • 引数にデフォルト値を設定することが出来るよ
  • デフォルト値を設定できるのは、引数の最後の方だけだよ

External Names for Parameters with Default Values

  • デフォルト値を設定すると、自動で外部引数名も設定されるよ
    なにもしないと、内部で使う引数名と同じものになるよ。
func join(s1: String, s2: String, joiner: String = " ") -> String {
    return s1 + joiner + s2
}
  • この場合、『joiner』が外部引数名になるよ
  • 呼び出す方はこんな感じになるよ
join("hello", "world")
// returns "hello world”

join("hello", "world", joiner: "-")
// returns "hello-world”

Variadic Parameters

  • 可変引数は0個以上の値を受け取る特殊な形だよ
  • 可変引数は型の後に『...』を書くよ
  • 可変引数は実際には配列になるよ
func arithmeticMean(numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }
    return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// returns 3.0, which is the arithmetic mean of these five numbers
arithmeticMean(3, 8, 19)
// returns 10.0, which is the arithmetic mean of these three numbers
  • 可変引数は引数の最後に書く必要があるよ
    デフォルト値も使う場合は、デフォルト値のさらに後に可変引数が来るよ。
    メモ: この認識で正しいのか? 要確認

Constant and Variable Parameters

  • 引数はデフォルトでは定数になるよ
    変数にしたい場合、引数の前に『var』を付けるよ。

In-Out Parameters

  • 引数として渡された値を関数で変更することが出来るよ
    この場合、引数の前に『inout』を付けるよ。

  • 関数を呼び出す側では、変数名の前に『&』を付けるよ

  • 入出力引数はデフォルト値を持てないよ
    可変引数にも出来ないよ。

  • 具体的には、関数はこんな感じになるよ

func swapTwoInts(inout a: Int, inout b: Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}
  • 呼び出す方はこんな感じになるよ
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
println("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// prints "someInt is now 107, and anotherInt is now 3

Function Types

  • 関数の型は引数や戻り値に使えるよ

Using Function Types

  • というか、関数の型は他の型と同じように扱えるよ

とりあえずここまで。 (2014/06/09)