前を向くために Part3

プログラミング、音楽、外交問題、その他思いついたことを何でも公開

人生、前向きに生きたいもの。でも、何かと後ろ向きになりがちな自分がいるのです。前向きに生きるには、まず前を向かなければなりませぬ。じゃあ前を向くためにはどうしたらいいの?と日々悩んどります。これはその記録の一部です。

天皇陛下の退位の何が問題なのか

1. 退位後の立場はどうなるのか

 過去の例では、上皇という呼称になるのが一般的らしいので、呼称は上皇としておく。さて、上皇とはどういう立場なのか。今まで退位が認められなかったので、当然、上皇の立場も、憲法にも皇室典範にも記載がない。

 今の天皇陛下でも、憲法に定められた国事行為を行う以外は何ら権利も義務も有しないのであるから、上皇になってそれら国事行為から解放されたら、何の権利も義務もなくなると考えられる。つまり、公的には何ら責務を負わず、何をする権利もないということになるのではないか。

 とはいえ、天皇にも、食事をしたり睡眠をとったり家族と家庭内対話をしたりということは許されているので、これら、いわば私的行為は、上皇にも許されると考えられる。つまり、上皇の立場とは、公的には何の行為も許されず、私的行為のみが許されるということになる。

 そうした場合、例えば旅行に行きたいと上皇が考えたら、それは叶うのか。今でも、全国の被災地などをよく行幸されている天皇陛下である。上皇になったら、天皇という立場を離れ、自由に日本や世界を飛び回り、日本国民に寄り添いたいと願うのは、想像に難くない。行幸は国事行為か。日本国憲法には、天皇が行う国事行為が列挙されているが、この中に、「行幸」はない。つまり、行幸は、国事ではないということだ。であるならば、天皇の私的行為であるということになる。そうであるならば、上皇の「旅行」も私的行為である。だから旅行をすることは、叶わないことはないであろう。

 なお、上皇も皇族になると思われる。現行の皇室典範では、皇太后が皇族として含まれるからだ。皇位継承権が生じるか同課はわからない。これから決めるのだろう。

 若干の懸念もある。退位したら、今の皇太子殿下が天皇になるのだから、天皇の親という立場にもなる。そうすると、家族内対話として、上皇天皇に、何かのアドバイスのようなものをすることは、十分に考えられる。それがアドバイスであるうちはいいかもしれないが、何しろ、実の親である。「親の言うことが聞けないのか」みたいな命令のようなものがもしあったとしたら、それは問題ではないだろうか。例えば、天皇は行きたいと思っていないのに、上皇に「被災地に行きなさい」と言われたら、天皇は逆らえるだろうか。この辺り、疑問が残る。

 更に言えば、「お前、もう天皇を退位して位を譲りなさい」などと言ったりしたら、これは大変である。上皇の恣意で天皇が決まるなどということがあってはならないだろう。

 天皇は、上皇の言うことを断れるのか。立場上は、断らなければならないと思われるが、実際問題としてどうなのか。繰り返すが、実の親である。

 

問題その1: 上皇天皇に命令することがありはしないかと懸念される。

 

2. 天皇に退位の恣意は許されるのか

 すでに述べたように、日本国憲法に定められている通り、天皇は、憲法に定められている国事行為のみを行うことができる。そのほかに認められているのは、私的行為に限られる。恣意的な発言は、私的行為のみが許され、公的行為では許されない。

 退位は公的行為である。私的行為ではあり得ない。であるならば、天皇が、恣意的に、つまり、自分が退位したいからといって、退位できるものではない。つまり、「やめたいからやめさせて」で退位できるものではないということである。さらに、公の場で「退位したい」と言うことも許されない。家庭内、つまり、皇后にぼやくのは、私的行為として許されるであろうが。

 つまり、そもそも、公共の電波を使って、国民に直接話された、あのビデオレターは、憲法違反だということになる。

 

問題その2: そもそも恣意的な退位もそれを表現することも憲法違反である。

 

  その責任は憲法第3条にあるように、内閣にあるのだが。

 だがしかし、放送されてしまった。覆水盆に返らず。国民は天皇陛下の気持ちを知ってしまった。ではどうするか、ということである。ボールは国民の側にある。

3. 恣意的退位の前例になる

 憲法違反をしてまで、自身の考えを述べられた天皇陛下が、実際に退位された場合、これは確実に、退位の前例になる。次の天皇陛下が、「だって前の陛下だってやめたいっておっしゃってやめたんだから、自分もやめたいからやめる」とおっしゃったらどうするのか。退位していただくのか。即位してすぐに「やっぱり天皇はきついからやめる」などとおっしゃった場合はどうするのか。そんなことが繰り返されたらどうなるか。天皇のなり手がいなくなってしまう。大問題だ。

 

問題その3: 前例になる。

 

4. 恣意的即位はできるのか

 恣意的に退位できるのなら、では即位も恣意的にできるのかという議論が待っている。恣意的な即位とは、「なりたいからなる」ということと「なりたくないからならない」ということの両方を含んでいる。つまり、皇太子が「天皇になりたいから陛下は退位なさってください」と言って現天皇を退位させて自分が即位することや、皇太子が「天皇になんかなりたくない」と即位拒否をすることである。少なくとも、天皇が恣意的発言をするのなら、皇太子だって発言したいだろう。即位拒否など、十分に考えられる。その場合、どうするのか。単純に、次の皇位継承権を持つ皇族になってもらうという話では済まない。次も拒否、その次も拒否などとなったら、やはり、天皇のなり手がいなくなってしまう。これも大問題である。

 

問題その4: 恣意的即位はどうするのか。

 

以上、問題点を4点あげた。考えれば、まだありそうな気がする。そんなことを、拙速に決めていいものだろうか。よくよく考えて、国民にも問題点を明らかにしながら議論を尽くし、国民の総意として決めるべきではないか。そのように思うのだが。

Swift言語ガイド 第7章 クロージャ

  1. クロージャとは自己完結型の機能ブロックである。C で言えばブロックに似ている。定義されたコンテキストにより、どんな定数にも変数にも格納可能で、「閉じている」ため、クロージャと呼ばれる。
  2. 関数は名前がついたクロージャということができる。逆に、クロージャは名前のない関数と言うと語弊があるが、最初のうちはこの理解でもよかろう。
  3. クロージャの一般形は以下。
    { ( 引数 ) -> 戻り値型 in
     文
    }
    
  4. 標準ライブラリにある sorted に渡すクロージャの例がとてもおもしろいので、これを追ってみる。sorted は、既知の型の配列をソートするもので、そのソートはユーザが提供するクロージャに基づいて行われるというものである。引数は2つ。ソートさせる配列と、引数を2つ取り、Bool を返すクロージャである。Bool 値は、2つ取る引数の最初の方が後の方より前にソートされるはずならば true を、そうでなければ false となるようにクロージャを作る必要がある。まずは最初のわかりやすい例から。これは文字列をアルファベットの逆順にソートするものである。関数(クロージャ)の型は (String, String) -> Bool である。

      1. まずは普通に関数を定義し、それを渡す。
        let names = [ "くるみ", "アル", "ひでかず", "はぎ", "くに" ]
        func backwards( s1: String, s2: String ) -> Bool {
         return s1 > s2
        }
        var reversed = sorted( names, backwards )
        
        上記の関数で s1 > s2 を返しているが、アルファベット順じゃなくて逆順ソートなので、true を返すのはクロージャの1番目の引数が2番目の引数より大きいときであるので、これで良い。この式がクロージャの本質である。
      2. これをインラインのクロージャにすると、次のようになる。これは完全にクロージャの一般形と同じ形をしている。
        var reversed = sorted(
         names, {
             ( s1: String, S2: String ) -> Bool in
             return s1 > s2
         }
        )
        
      3. それで、sorted に渡すクロージャの戻り値は Bool であると決められているので -> Bool は省略できる。また引数の型も渡す配列から推論できるので省略できる。そうすると、1行に入ってしまって次のように書くことができる。
        var reversed = sorted( names, { s1, s2 in return s1 > s2 })
        
      4. 式一つしかないクロージャは暗黙にその式の結果を戻り値にするので、return も省くことができる。
        var reversed = sorted( names, { s1, s2 in s1 > s2 })
        
      5. Swift$0, $1, $2, ... という省略形の引数名をクロージャに使えるので、これを使えば引数定義の部分を省略することができる。引数部分も戻り値部分もなければ、in も省略できる。そうするとこうなる。
        var reversed = sorted( names, { $0 > $1 })
        
      6. Swift の文字列型は、独自に大なり比較演算子を関数として定義しているので、それを使えばさらに短くでき、なんと1文字で済んでしまう。
        var reversed = sorted( names, > )
        
      7. クロージャをここまで短くすることができるという例である。どこまで省略して書くかは個人の好みの問題だと思うが。

  5. 末尾クロージャ Trailing Closures は、クロージャー式を関数の最後の引数として渡す場合に使われるもので、この場合、クロージャ式は渡す先の関数の引数のかっこの外側に書くことができる。なお、クロージャ式が関数のただ一つの引数の場合で、それを末尾クロージャとして書く場合は、関数呼び出し時に () を付ける必要はない。
    func callee( closure: () -> () ) {
     // callee の実行部
    }
    // callee を普通に呼ぶ呼び方
    callee( {} )
    // 終了クロージャだとこうなる。
    callee(){}
    
  6. 末尾クロージャを使えば、reversed 関数はこう書ける。
    var reversed = sorted( names ) { $0 > $1 }
    
  7. 末尾クロージャは特に、クロージャが長くてインラインでは収まらない時などに便利である。Swift の持つ Array 型の map メソッドはただ一つの引数としてクロージャ式を取るが、その例は以下。
    let digitNames = [ 0: "ゼロ", 1: "いち", 2: "に", 3: "さん", 4: "よん", 5: "ご", 6: "ろく", 7: "なな", 8: "はち", 9: "きゅう" ]
    let numbers = [ 16, 58, 510 ]
    let strings = numbers.map {
     ( var number ) -> String in
     var output = ""
     while number > 0 {
         output = digitNames[ number %10 ]! + output
         /* ディクショナリの添字記法はオプショナルを返すがこの場合は必ずあるので ! をつけている。 */
         number /= 10
     }
     return output
    }
    
  8. クロージャは、それを定義した時の周りのコンテキストから定数や変数を「キャプチャ(取り込み capture)」できる。そしてそれらの値を、たとえ周りのコンテキストがないところでも参照したり変更したりできる。ネストした関数が外側の関数の定数や変数を使えるのはこのためである。
  9. クロージャは参照型である(値型ではない)。なので関数もまた参照型である。従って、例えば2つの定数にクロージャを別々に代入したとしても、実体は両方とも同じクロージャを指す。
  10. 関数はおなじみだがクロージャは割と新しい気がする。使いこなせば、sorted のところで見たように、強力な武器となろう。

(第7章 クロージャ 終わり)

Swift言語ガイド 第6章 関数

  1. 関数には必ず名前がある。
    func sayHello( personName: String ) -> String {
        let greeting = "こんにちは、" + personName + "。"
        return greeting
    }
    println( sayHello( "あんな" ) )
    
  2. 引数がない場合でもかっこは必要。定義にも呼び出しにも。
    func sayHelloWorld() {
        println( "Hello, world" )
    }
    sayHelloWorld()
    
  3. 戻り値がない関数は、実は Void という型の戻り値を持っている。Void は空のタプルで、() と書く。
  4. 複数の戻り値がある関数を定義する場合は、戻り値にタプルを用いる。タプルの要素に名前をつけることもでき、その場合は関数の外でその名前が使える。
    func minMax( array: [ Int ] ) -> ( min: Int, max: Int ) {
        ...
    }
    println ( minMax.min( [ 1, 100, 1000 ]))
    
  5. オプショナルなタプルも使える。この場合、タプル全体がオプショナルとなる。
    func minMax( array: [ Int ] ) -> ( min: Int, max: Int )? {
        if array.isEmpty { return nil }
        ...
    }
    
  6. 外部引数名(External Parameter Names)とは、普通は関数内でしか見えない引数名を外部からも見えるようにする引数名で、関数呼び出し時(外部である)に使うことができる。こうすると1つの引数に2つの名前(外部名と内部名)がつくことになる。外部引数名を付ける時は、必ず外部引数名、空白、(通常の)内部引数名の順に書かなければならない。また、外部引数名を付ける時は、必ずそれを指定して引数にしなければならない。引数の順番に頼ってはいけないということである。
    func join( string s1: String, toString s2: String, withJoiner joiner: String ) -> String {
        return s1 + joiner + s2
    }
    let longString = join( string: "Hello", toString: "world", withJoiner: ", " )
    
  7. 外部引数名も内部引数名も同じでよいならば(つまり1つで済ませるならば)、引数名の直前にハッシュ(#)を付ければよい。
    func containsCharacter( #string: String, #character: Character ) -> Bool {
        for current in string {
            if current == character {
                return true
            }
        }
        return false
    }
    let hasCharacter = containsCharacter( string: "Hello", character: "o" )
    
  8. 引数にデフォルト値が定義してあれば、呼び出し時に引数を省略することができる。こういう引数は引数軍の最後にまとめた方がよい(必須ではないが)。
    func join( string s1: String, toString s2: String, withJoiner joiner: String = " " ) -> String {
        return s1 + joiner + s2
    }
    
  9. デフォルト値のある引数は、必ず外部名も存在する。コードで指定してあればそれが使われ、指定してなければ Swift が勝手に内部名と同じ外部名を付ける。一応、それが嫌なら外部名にアンダースコアを指定すればいいことになっているが、こうなってくると親切を通り越してお節介のようにも思えるのだが、言語仕様としてどうなんだろう? C の「簡潔に」という思想は、Swift には通用しないようだ。
    func join( s1: String, s2: String, joiner: String = " " ) {
        ...
    }
    join( "hello", "world", joiner: ", " )
    
  10. 可変長引数(Variadic Parameters)は、ゼロかそれ以上の値を受け付ける引数である。これを定義するには、引数の型名の後に ... をつける。これは関数内部ではその型の配列として見えるようになる。ただし、関数が持てる可変長引数は最大1個だけであり、常に引数リストの最後でなければならない。デフォルト値付き引き数よりも後である。
    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 )
    
  11. 可変引数(Variable Parameters)は引数定義に var をつける。こうすると、通常は関数内では変更できない引数が変更可能になる。ただし、関数の中だけで有効で、呼び出し元の(つまり外部の)変数の値までは変更できない。あくまでローカル変数である。
    func alignRight( var string: String, count: Int, pad: Character ) -> {
        string = padString + string
        ...
    }
    
  12. 可変引数とは異なり、In-Out 引数は引数の外部の値も変更可能つまり関数が終了した後も変更が残る。これを定義するには、引数定義に inout キーワードをつける。In-Out 引数に指定できるのは、外部において変数として宣言してあるものでなければならない。定数やリテラルは指定できない。また、呼び出し時に引数の直前に & を付ける必要がある。さらに、In-Out 引数はデフォルト値を持つことはできず、可変長引数にもできない。もちろん varlet も付けられない。
    func swapTwoInts( inout a: Int, inout b: Int ) {
        let temp = a
        a = b
        b = temp
    }
    var someInt = 3
    var anotherInt = 107
    swapTwoInts( &someInt, &anotherInt )
    
  13. 関数の型は、引数の型と戻り値の型からなる。関数を型とする定数や変数も宣言可能。
    func addTwoInts( a: Int, b: Int ) -> Int {
        return a + b
    }
    func multiplyTwoInts( a: Int, b: Int ) -> Int {
        return a * b
    }
    var mathFunc: ( Int, Int ) -> Int = addTwoInts
    mathFunc = multiplyTwoInts
    
  14. 関数には型があるので、型さえ合えば別の関数の引数になれる。
    func printMathResult( mathFunction: ( Int, Int ) -> Int, a: Int, b: Int ) {
        println( "結果: \( mathFunction( a, b ))" )
    }
    printMathResult( addTwoInts, 3, 5 )
    
  15. 同様に、関数の戻り値にもなる。
    func stepForward( input: Int ) -> Int {
        return input + 1
    }
    func stepBackward( input: Int ) -> Int {
        return input - 1
    }
    func chooseStepFunction( backwards: Bool ) -> ( Int ) -> Int {
        return backwards ? stepBackward : stepForward
    }
    
  16. 関数はネストできる。
    func chooseStepFunction( backwards: Bool ) -> ( Int ) -> Int {
        func stepForward( input: Int ) -> Int { return input + 1 }
        func stepBackward( input: Int ) -> Int { return input - 1 }
        return backwards ? stepBackward : stepForward
    }
    

(第6章 関数 終わり)

Swift言語ガイド 第5章 制御の流れ

for-in ループ

  1. 数のレンジに使う例。


    for i in 1...5 {
    println( "5の倍数は \( i * 5 )" )
    }
  2. もしレンジの個々のインデックス値が不要であれば、アンダースコアにすることもできる。


    let base = 3
    let power = 10
    var answer = 1
    for _ in 1...power {
    answer *= base
    }
    println( answer )
  3. 配列に使う例


    let names = [ "ジョン", "ポール", "ジョージ", "リンゴ" ]
    for name in names {
    println( "こんにちは、\( name )。" )
    }
  4. ディクショナリに使う例。この場合、インデックスは (key, value) のタプルになる。ディクショナリは順不同なので、定義した順に出てくるとは限らないことに注意。


    let numberOfLegs = [ "クモ": 8, "アリ": 6, "ネコ": 4 ]
    for ( animalName, legCount ) in numberOfLegs {
    println( "\( animalName ) の足は \( legCount ) 本。" )
    }
  5. 文字列中の文字に使う例


    for character in "こんにちは" {
    println( character )
    }

for ループ

  1. C などに見られるのと同じ、条件とインクリメントでループする形。ループの1回が終わるごとにカウンターを増やしながら、特定の条件になるまでループを繰り返す。


    for var i = 0; i < 3; ++i {
    println( i )
    }
  2. この形を一般形は以下。ちなみに、初期化、終了条件、インクリメントの部分にかっこは不要。


    for 初期化; 条件; インクリメント {

    }
  3. これは以下と等価。


    初期化
    while 条件 {

    インクリメント
    }
  4. 初期化式に現れた定数や変数は for ループのスコープ内でだけ有効である。もしインデックス値の最後の値を for ループの後に参照したい場合は、ループのスコープが始まる前にインデックスを宣言しておかなければならない。


    var i: Int
    for i = 0; i < 3; ++i {
    println ( i )
    }
    println( "インデックスの最終値は \( i )" )

while ループと do-while ループ

  1. while ループは、ある条件が false になるまで文の集合を繰り返す。あらかじめループの回数がわからない場合などによく使われる。Swift では whiledo-while の2つの形式があり、while はループの最初で条件が評価され、do-while はループの最後で条件が評価される。
  2. while ループの一般形は以下。


    while 条件 {

    }
  3. do-while ループの一般形は以下。


    do {

    } while 条件

条件文

  1. Swift には if 文と switch 文の2つがある。
  2. 条件部分にかっこがいらない。でもこれは while などでも同じ。
  3. if 文は else if でチェイン可能。
  4. switch 文では default は必須であり、必ず最後になければならない。
  5. casebreak しなくとも1つの実行で完了する。下の caseに移りたい場合は fallthrough キーワードを使う。詳しくは後述。
  6. それぞれの case は最低1つの実行文がなければならない。
  7. 1つの case に2つ以上の値を書く場合はコンマで分ける。複数行になってもよい。


    switch 条件式 {
    case 値1,
    値2:
    実行文
    default:
    実行文
    }
  8. case は範囲でもよい。


    let count = 3_000_000_000_000
    let countedThings = "天の川の星の数"
    var naturalCount: String
    switch count {
    case 0:
    naturalCount = "no"
    case 1...3:
    naturalCount = "a few"
    case 4...9:
    naturalCount = "several"
    case 10...99:
    naturalCount = "tens of"
    case 100...999:
    naturalCount = "hundreds of"
    case 1000...999_999:
    naturalCount = "thousands of"
    default:
    naturalCount = "millions and millions of"
    }
  9. 1つの switch 文の中でタプルを使えば、複数の値をテストすることができる。それぞれのタプルの要素は別々の値のレンジに対してテストできる。アンダースコアを使えば、どんな値にもマッチ可能。


    let somePoint = ( 1, 1 ) // ( Int, Int ) のタプル
    switch somePoint {
    case ( 0, 0 ):
    println( "( 0, 0 ) は座標の原点。" )
    case ( _, 0 ):
    println( "( \( somePoint.0 ), 0 ) は X 軸上にある。" )
    case ( 0, _ ):
    println( "( 0, \( somePoint.1 ) ) は Y 軸上にある。" )
    case ( -2...2, -2...2 ):
    println( "( \( somePoint.0 ), \( somePoint.1 ) ) は箱の中にある。" )
    default:
    println( "( \( somePoint.0 ), \( somePoint.1 ) ) は箱の外にある。")
    }
  10. 複数case が重なってもよい。そういう場合は、上から調べて最初にマッチした case が選択される。
  11. バインディング(Value Bindings)と呼ばれる一時的な定数や変数へのバインディングができ、そうすればその定数や変数を実行文で使用できる。


    let anotherPoint = ( 2, 0 )
    switch anotherPoint {
    case ( let x, 0 ):
    println( "X軸上で X の値は \( x )" )
    case ( 0, let y ):
    println( "Y軸上で Y の値は \( y )" )
    case let ( x, y ): // これがキャッチオールの役目をするので default はなくてもよい。
    println( "( \( x ), \( y ) ) というどこか。")
    }
  12. switchcase は、さらに where 句によって付加的な条件をチェックすることができる。


    let yetAnotherPoint = ( 1, -1 )
    switch yetAnotherPoint {
    case let ( x, y ) where x == y:
    println( "( \( x ), \( y ) ) は x == y の線上にある。" )
    case let ( x, y ) where x == -y:
    println( "( \( x ), \( y ) ) は x == -y の線上にある。" )
    case let ( x, y ):
    println( "( \( x ), \( y ) ) はどこか別の場所。")
    }

制御移動文 Control Transfer Statements

  1. continue 文は、ループでやっていることを止め、次のループに移動する。for ループのインクリメントがある場合はインクリメントは評価される。スキップされるのは、ループの実行文の部分だけである。
  2. break 文は、制御の流れをコントロールする文全体をただちに終わらせる。break 文は switch 文かループ制御文の中に使うことができ、それ以降の実行を終了させる。switch 文であれば、制御を switch 文の閉じかっこ } の次に移動させるし、ループであればループの閉じかっこ } の次に移動させる。無視させたい(つまり何もしない)case のところに使うこともできる。これは単にcase 条件句: break と書けばよい。この場合、分岐は一致し、break 文によってただちに switch 文を抜け出す。


    let numberSymbol: Character = "三"
    var possibleInteger: Int?
    switch numberSymbol {
    case "1", "一":
    possibleInteger = 1
    case "2", "二":
    possibleInteger = 2
    case "3", "三":
    possibleInteger = 3
    case "4", "四":
    possibleInteger = 4
    default:
    break
    }
  3. fallthrough 文は、C のように複数のケースを実行させたい時(下に行きたい時)に使う。
  4. ラベル付き文はラベル名に続けてコロンをつけたループ文や switch 文である。ラベルを使えるのは break 文か continue 文に続けてラベル名を指定する場合らしいが、これは文法編を参照のこと。さしあたり必要性を感じないので深く追求はしない。

2014年11月04日のTweet

Swift言語ガイド 第4章 コレクション型

配列

  1. 配列は同じ型での値の順序付きコレクションである。
  2. 配列の型は Array<型> と書くか、または省略形で [型]と書く。省略形の方が好ましい。


    var arraySample1: Array<String>
    var arraySample2: [ String ]
  3. 配列リテラル[ 値1, 値2, 値3 ] のようにコンマで区切り、大かっこで囲んで書く。


    var shoppingList = [ "卵", "牛乳" ]
  4. 配列の要素数を調べるには count プロパティを使う(リードオンリー)。


    println( "買い物リストには買う物が \( shoppingList.count ) 個ある。" )
  5. 配列が空かどうかを調べるには、isEmpty プロパティを使う(Boolean)。

    if shoppingList.isEmpty {
    println( "買い物はない。" )
    } else {
    println( "買い物が必要。" )
    }
  6. 配列の最後に要素を加えるには append メソッドを使う。+= も使える。これだと1度に複数の要素を加えられる。

    shoppingList.append( "小麦粉" )
    shoppingList += [ "ベーキングパウダー", "バター","チーズ", "チョコレート" ]
  7. 配列の要素を参照するには配列名の直後に [ 添字 ]を付ける。これを添字記法と呼ぶ。


    var firstItem = shoppingList[ 0 ]
  8. 配列の最初の要素の添字は 0 である。
  9. 配列の要素を変えるのも添字記法でできる。


    shoppingList[ 0 ] = "卵6個"
  10. 1度に複数の要素を変えるには範囲演算子 ... が使える。変更される要素数と変更する要素数が異なってもかまわない。


    shoppingList[ 4...6 ] = [ "バナナ", "りんご" ]
  11. 配列の最後に要素を加えるのには添字記法は使えない。
  12. 配列の要素数を超えて参照や代入をしようとするとランタイムエラーになる。
  13. 配列の特定の添字の所に値を挿入するには insert( atIndex: ) メソッドを使う。


    shoppingList.insert( "メイプルシロップ", atIndex: 0 )
  14. 配列から特定の添字の所の要素を削除するには remove( 添字 ) メソッドを使う。このメソッドは、戻り値として配列を返すのではなく、削除した要素を返すので注意。要素を削除した場合、ギャップは前に詰められるので、その要素の後ろの要素が前にずれることになる。


    let mapleSyrup = shoppingList.removeAtIndex( 0 )
    println( shoppinglist[ 0 ] )
  15. 配列の最後の要素を削除する場合には removeLast メソッドを使う。


    let apples = shoppingList.removeLast()
  16. 配列全体に繰り返し処理をするには for-in ループが使える。もし配列の値だけでなく、添字も必要なのであれば、グローバル関数 enumerate が使える。enumerate 関数は、配列の個々の要素の添字と値のタプルを返す関数である。


    for item in shoppingList {
    println( item )
    }
    for ( index, value ) enumerate( shoppingList ) {
    println( \( index + 1 ) 個目は \( value ) )
    }
  17. 要素が空の配列を作るには、イニシャライザ記法が使える。すでに型がわかっている場合は型名を省略できる。


    var someInts = [ Int ]()

    someInts.append( 3 )
    someInts = []

  18. 幾つかの要素に同じ値を入れて初期化した配列を作るには countrepeatedValue を使って書くことができる。


    var threeDoubles = [ Double ]( count: 3, repeatedValue: 0.0 )
  19. 2つの型コンパチな配列を + を使って合成して一つの配列を作ることもできる。新しい配列の型は推論される。


    anotherThreeDoubles = [ Double ]( count: 3, repeatedValue: 2.5 )
    var sixDoubles = threeDoubles + anotherThreeDoubles

ディクショナリ

  1. ディクショナリは同じ型での値の順不定なコレクションである。違う型でもいい NSDictionary などとは異なるので注意。
  2. ディクショナリの値はユニークな識別子であるキーに関連付けられる。
  3. ディクショナリの型は Dictionary< キーの型, 値の型 > と書くか、省略形として [ キーの型: 値の型 ] と書く。省略形の方が好ましい。
  4. ディクショナリのリテラルの一般形は [ キー1: 値1, キー2: 値2, キー3: 値3 ] のようなキーバリューペアである。リテラルを使えば、型宣言をする必要はほとんどない。


    var airports = [ "HND": "羽田空港", "NRT": "成田空港" ]
  5. ディクショナリを参照したり変更したりするには、メソッドやプロパティ、添字記法を用いる。配列と同様に使えるものは以下。


    println( airports.count )
    println( airports.isEmpty )
    airports[ "KIX" ] = "関西空港" // 値の追加
    airports[ "HND" ] = "東京国際空港" // 値の変更
  6. 代入や変更には updateValue( forKey: ) も使えるが、これは古い(変更される前の)値を返すので注意のこと。


    if let oldValue = airports.updateValue( "成田国際空港", forKey: "NRT" ) {
    println( "\( oldValue ) は NRT の更新前の名前である。" ) // 「成田空港」が出力される。
    }
  7. 参照は添字記法でできるが、キーバリューペアが登録されていない場合でも参照はエラーにはしない。このため、戻り値は値の型の Optional 値となる。(なのでたぶん、参照時は if-let を使ったほうがいい。)


    if let airportName = airports[ "KIX" ] {
    println( "空港名は \( airportName )" )
    } else {
    println( "その空港は登録されていない。")
    }
  8. キーバリューペアの削除は、添字記法で nil を代入すればよい。


    airports[ "APL" ] = "アップル国際空港"
    airports[ "APL" ] = nil
  9. 削除のもう一つの方法は、removeValueForKey を使う。この場合、Optional 的処理が必要なので注意のこと。


    if let removedValue = airports.removeValueForKey( "NRT" )
    println( "\( removedValue ) は削除された。" )
    } else {
    println( "そのような空港は登録されてない。")
    }
  10. ディクショナリの繰り返し処理でも for-in ループを使うと便利だが、回すのは ( key, value ) となる。


    for ( airportCode, airportName ) in airports {
    println( "\( airportCode ): \( airportName )" )
    }
  11. keys プロパティと values プロパティを使えば、キーだけ、値だけの配列を取り出すことができる。


    let airportCodes = [ String ]( airports.keys )
    let airportNames = [ String ]( airports.values )
  12. 空のディクショナリを作るには、イニシャライザ記法を使う。配列と同様、すでに型がわかっている場合は、型を省略できる。


    var namesOfIntegers = [ Int: String ]()
    namesOfIntegers[ 16 ] = "sixteen"
    namesOfIntegers = [:]
  13. キーの型はハッシュ可能でなければならない。つまり、ハッシュ値を提供可能な型でなければならない。ハッシュ値hashValue で計算できる。Swift のすべての基本型(String, Int, Double, Bool)はすべてハッシュ可能であるので、キーになり得る。また値が関連付けられていない Enumeration メンバーもデフォルトでハッシュ可能である。
  14. 自分で作ったカスタムの型も、Swift 標準ライブラリの Hashable プロトコルに準拠すれば、キーにすることができる。Hashable プロトコル準拠は
    1. hashValue という名前の Int 型プロパティが得られること。
    2. 等価比較演算子==)を提供すること。
    を満たす必要がある。詳しくはプロトコルの章を参照のこと。

(第4章コレクション型終わり)

2014年11月03日のTweet