Posted by あしたさぬき.JP at ◆

 

この広告、メッセージは90日以上更新のないブログに表示されています。
新しい記事を書く事でこのメッセージが消せます。
  

2014年10月27日
Posted by 屋台ブルー at ◆ 2014年10月27日00:00 Comment(0)

Swiftで遊ぼう! - 108 - Swift Fundamentals本 イーナム

swift_logoSwift Fundamentals: The Language of iOS Development - スイフト:基本」はまだまだ続く。

さて、少しずつ、焦らずSwiftの理解を深くしていきます。まだ深い理解ができていないイーナムの復習をする。
書かれていることは分かるけど、どういう風に利用していくんでしょうね。コードの勉強が不可欠だけどもう少し理解をすすめてから取り組む。

じゃあ章末の問題に取り組む。

Questions for Review - 復習のための質問

1. イーナムレーションを使うのは、似たようなデータグループを扱う作業を型に安全にするためです
a) 正しい
b) 間違い
これが使用理由で答えは(a)ですね。

2. イーナムの適切な宣言法は?
a) enum myEnum { // member definition }
b) func myEnum: enum { // member definition }
c) var myEnum: enum = { // member definition }
d) let enum myEnum = { // member definition }
これは(a)で問題ありませんね。

3. イーナム型の変数を宣言する時に定義されていないメンバーを割り当てるとどうなりますか?
a) 新しいイーナムメンバーが定義される
b) デフォルトのメンバーが使用される。
c) Xcodeは型エラーを出す
d) 何も起こらない。無視される。
これは(c)のエラーですね。

4. イーナムレーションを使用する状況として相応しいのは次のどれ?
a) 年間の月別
b) テクノロージー会社のリスト
c) 太陽系の惑星
d) 上記すべて
イーナムレーションは有限の値を扱うのに適していると思われたので、(a)と(c)は間違いないと思ったけど、会社のリストにも相応しいんですね。答えは(d)です。

じゃあ今日はここまで。
  


2014年08月23日
Posted by 屋台ブルー at ◆ 2014年08月23日00:00 Comment(0)

Swiftで遊ぼう! - 44 Enumerationの理解を深める

swift_logoSwiftの言語体系をおおまか理解したと思っていたのは幻想です。考えてみれば、まだ教科書(The Swift Programming Language)を読破もできていないし、理解もできていない。読んだところもドンドン忘れている。イーナム型の応用例が、入れ小タイプ(Nested Type)の説明にあったので、じっくり考えてみよう。

struct BlackjackCard {
まず、struct型のBlackjackCardを作っているが、これで何を実現したいのか先に説明した方が理解しやすいだろう。ブラックジャックのルールを知らなくてもいい。トランプの種類(Spades、Hearts、Diamonds、Clubs)と数字(Ace、Two、Three、Four〜)を与えると、種類の記号とブラックジャックのルールで決められた値を返すというもの。ブラックジャックでは、Ace(エース)には「1」か「11」のどちらかを選べるルールがあり、絵札(Jack、Queen、King)は一律「10」で後は数字の値を使う。これを実現するためのstruct型BlackjackCardである。まず、イーナム型Suitで4種類のトランプの種類を区別する。そして、イーナム型のRankでブラックジャックで使われる値を設定するが、当然Aceには2種類の値を持つことになるので、これを実現するためにイーナム型Rank内にstruct型Valuesで2つの値を設定している。

enum Suit: Character {
case Spades = "♠︎", Hearts = "♡", Diamonds = "♢", Clubs = "♣︎"
}
先ほど説明した、トランプの種類を区別するイーナム型Suitの宣言である。ここで私のような素人が勘違いするのが、これは宣言だけなので、これはまだ利用できない。取りあえずメンバー変数があり、ローバリューとしてキャラクター型の記号が与えられるので、このインスタンスが生成されたら利用できるようになる。

enum Rank: Int {
case Two = 2, Three, Four, Five, Six, Seven, Eight, Nine, Ten
case Jack, Queen, King, Ace
struct Values {
let first: Int, second: Int?
}
var values: Values {
switch self {
case .Ace:
return Values(first: 1, second: 11)
case .Jack, Queen, King:
return Values(first: 10, second: nil)
default:
return Values(first: self.toRaw(), second: nil)
}
}
そして少しややこしいイーナム型Rankの宣言部分。ある意味、ここがキモになるだろう。Rankにもカードの数だけのメンバー変数が与えられている。しかし、Aceは値が2つあるので、単純にローバリューで対応することができない。ここでプロパティとしてstruct型Valuesで宣言したインスタンスvaluesが2つの値、Int型firstとオプショナルなsecondが指定されている。このプロパティもイーナム型Rankを宣言しているこの段階で生成はされない。Rankが生成されるときに、メンバー変数の指定に従って、valuesが生成(初期化?)される仕組みになっている。

}

let rank: Rank, suit: Suit
ここが、プロパティの生成段階である。これで、イーナム型Rankのインスタンス、rankが生成される。しかし、ここに初期化ステップが記載されていないため、初期化のためにメンバーワイズ・イニシャライザーを使わなければならない。Suitのインスタンスsuitも同様で、メンバーワイズ・イニシャライザーが必要。しかし、valuesは自動的に生成されるので、記述の必要はない。

var description: String {
var output = "suit is \(suit.toRaw()),"
output += " value is \(rank.values.first)"
if let second = rank.values.second {
output += " or \(second)"
}
return output
}
これはメソッドにあたるが、ここにパラメーターの設定はないので、インスタンスが生成された時点で、このメソッドが使えるようになる。
}

let theAceOfSpades = BlackjackCard(rank: .Ace, suit: .Spades)
このStruct型BlackjackCardのインスタンスを生成するためにプロパティの初期値をメンバーワイズ・イニシャライザーを使って指定しなければならない。それぞれのメンバー変数が引数になる。特にrank生成時に渡すメンバー変数によって、struct型Valuesのプロパティのインスタンス生成が始まるが、switch文で割りふられて引数が変化するしくみ。returnでインスタンスのvaluesが戻っていく。よく考えられた構造だけど、これを自分で思いつくかと言われれば、全くできない。先人の知恵だね。こういう仕組みを考えられる人は凄いね。でも、こういう仕組みが読めるようになると、ちょっとプログラミングが分かったような気がする(^^;)

println("theAceOfSpades: \(theAceOfSpades.description)")
//theAceOfSpades: suit is ♠︎, value is 1 or 11  


2014年08月21日
Posted by 屋台ブルー at ◆ 2014年08月21日00:00 Comment(0)

Swiftで遊ぼう! - 42 Enumerationもう一度深く考える

swift_logo「Enumerations」という型が、Swift言語にはあって、私には初耳で理解しにくく1回読んだだけで覚えられなかった。完全にArray型(配列)と混同してしまっていた。全く異なる次元の話なのに... 日本語訳が「列挙型」なんでArray(配列)と重なってしまった。もう一度、ちゃんと読み直す。シンタックスは「enum」と記述するので、「イーナム」と読むようだ。日本語表記は「列挙型」だけど、Arrayの日本語表記「配列型」と似ていて間違えるから「イーナム型」と「アレー型」という表記にしていく(将来変更するかもしれません)。異論があればコメントくだささい。

さて、イーナム型のデータを作るとき、必ずメンバーを作らなければならない。このメンバーに型宣言はいらない。実はこのメンバーは値じゃないけど、イーナムのメンバー値(member value)という説明がされているから混乱しそうになる。このメンバー値を宣言したところで、イーナム型の空箱にラベル用意するようなものかな?

enum Goods {
case Grape, Orange, Strawberry, Juice, Rice
}

どちらかと言えば、メンバー値は商品につけるラベルのような扱いなんだろうか、メンバー値を単独で取り回すことができないけど、イーナム型のインスタンスを生成した時にどのラベルにするのか決定ができる。

var whichGoods = Goods.Grape

こうしてやると、whichGoodsにGrapeのラベル付きの箱ができたような感じなんだろう。それをJuceのラベルに変えるのは以下のようにする。

whichGoods = .Juice

ラベルなので値ではなく、単なる識別名だよね。これがメンバー値のイメージだろうか? 頭が硬いのでなかなか納得できない。

そして、このメンバー値にAssociated Value(関連値)を割りふることができる。というか、このAssociated Value(関連値)がイーナム型変数を使うにしても、この関連値が無いと意味ある使い方はできないように思える。

この関連値、どんな型の値でも保持させることができる。

enum Barcode {
case UPCA(Int, Int, Int, Int)
case QRCode(String)
}

例文に載っているのが上記のイーナム型Barcodeであるが、ラベルとしてのメンバー値が2つあり、それぞれ関連値として異なる「型」が指定されている。UPCAはInt型の値を4つとるか、QRCodeのString型の値をとるか選ぶことができる。

しかし、このイーナム型の関連値、利用するのにswitch(スイッチ)文しかないような。でも、イーナム型のデータ、確かメンバー値に関数も取れたような。この関連値は関数で利用することもできるんでしょうか?

var productBarcode = Barcode.UPCA(8, 79347210, 4839218, 9)


switch productBarcode {
case .UPCA(let numberSystem, let manufacturer, let product, let check):
println("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).")
case .QRCode(let productCode):
println("QR code: \(productCode).")
}

イーナム型の関連値はインスタンスを生成してスイッチで指定す流必要があるが、この関連値を外から利用する方法は無いんじゃないかな。実はイーナム型データを実際のプログラムで利用するために次のRaw Value(ローバリュー)の組み合わせが必須なんでしょう。

enum Planet: Int {
case Merrcury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}

let earthsOrder = Planet.Earth.toRaw()

ここで重要なメソッドが、「toRaw()」と「fromRaw()」

イーナムの応用例は次の話題にする。イーナム、なんかピントきませんね。