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

 

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

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

Swiftで遊ぼう! - 193 - アプリを作ろう Closure(クロージャ)

UIAlertActionクラスの初期化パラメーターのhandlerで少々悩んでいる。

久しぶりにクロージャーが出てきたが、ここでも散々悩んでいるよね。

具体的なクロージャーの使い方が実際のコード内に出てきているので要チェック!

皆さん! はてなに来て、来て〜!
Swiftで遊ぼう! on Hatena
http://yataiblue.hatenablog.com  


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

Swiftで遊ぼう! - 15 クロージャ(Closures)は苦労じゃ

swift_logo2014年9月7日追記:クロージャに関して書いた記事(7月21日-23日)をまとめて理解したことを追記する。前の記事はそのまま残す。

Swiftの標準ライブラリにあるソート関数(特定の順番にアレー値を並べかえる)「sorted」の勉強をしている時にクロージャーの利便性が理解できたので、ちょっと説明をする。

「sorted」関数←(sortt関数ではないので注意!)の説明をすると、ふたつの引数が必要で、1つは「ある特定の型のアレー値」そして、「その特定の型の2つのアイテムを比較してBool値を返す関数」をわたす事で、与えられた型と同型で同サイズのアレー値を新しく作って戻す関数である。これをコードで書くと
var numbers:[Int] = [9, 4, 3, 1, 6, 7]
var numbersA = numbers

func forwads(s1: Int, s2: Int) -> Bool {
return s1 < s2
}
var numbersB = sorted(numbersA, forwads)

numbersAは[9, 4, 3, 1, 6, 7]
numbersBは[1, 3, 4, 6, 7, 9]

ここまでは、標準ライブラリsorted関数の説明であるが、ソートさせる度に関数(forwards)を作って(たぶんこの関数のことを比較関数と呼ぶんでしょう)、引数としてわたすのが面倒くさいから、引数として関数そのものをわたしてしまえってのがクロージャだろう。

var numbersC = sorted(numbersA, { (n1: Int, n2: Int) -> Bool in return n1 < n2 })

numbersAは[9, 4, 3, 1, 6, 7]
numbersCは[1, 3, 4, 6, 7, 9]

とここまではクロージャの基本形で、以前理解していたであろうギリギリのレベルです。実はここからクロージャのもう一つ進んだ機能がある。Swiftは非常に強力な型推測(Inferring Type)を持っている。

まず、標準ライブラリを熟知していないと使えないので、もう一度sorted関数を復習しておこう。ある特定の型で構成されたアレー型の値(ここではInt型)を与える。次に与える引数は比較関数だけど、この関数の2つの引数は、sorted関数に与えるアレー型値と同じ型(ここではInt型)でなければならない。という事は、推測機能が働きますね。といクロージャ内のパラメーターに型宣言は要らなくなるって事です。

また、比較関数がbool値を返すことも知っているので、それも要らない。returnも省略できる。また比較関数のパラメーターはアレー型の構成要素ということも知っているので、それぞれのインデックスにあたる$0と$1を使えば引数も省力できるから。結局、

var numbersD = sorted(numbersA, {$0 < $1})

numbersAは[9, 4, 3, 1, 6, 7]
numbersDは[1, 3, 4, 6, 7, 9]

とクロージャーの凄いとことが理解できました。

そして、もう一つのクロージャーの機能を知っておく必要がある。それはトレイリング・クロージャだ。関数のパラメーターとして与えるクロージャーが長く助長になる場合は。関数の引数を与える()から外に出してやることができるんです。

上の書き方を次のようにしてもいいんですよ。

var numbersD = sorted(numbersA) {$0 < $1}

まだ、クロージャをすべて理解しているわけではないが、今日はここまで。

おっと、The Swift Programming Language本では、もう一つ型推測の究極をのせてあった
var numbersD = sorted(numbersA,<)
-----
2014年7月21日:Swiftで遊ぼう! - 13 クロージャーで苦労じゃー!
なぜ、あしたさぬきで、プログラミングの話題を取りあげているのでしょう。プログラミングという全く未知の領域を勉強することで認知症の予防にしているつもり。でも、頭が硬いせいで、なかなか理解できない。馬鹿にされても仕方ないけど、まだまだよく解らないことだらけだ。

クロージャー... なんだこれは?です(^^;)

関数を変数に指定できるけど、なぜクロージャーって言うんでしょう。一番簡単なクロージャーの説明は以下の例文

func sayHellofunction() {
println("Hello from Function")
}

sayHellofunction()

var sayHelloClosure:()->() = {
println("Hello from Closure")
}

sayHelloClosure()

sayHelloClosure = sayHellofunction

sayHelloClosure()

この説明には、sayHelloClosureは変数なので、"Hello from Closure"って表示されていたけど、関数で置き換えてやれるので、"Hello from Function"に切り替わっている。このように関数を変数にすることができるけど、クロージャーってどういう意味? まだまだクロージャーの勉強を続けよう。

-----
2014年7月22日:Swiftで遊ぼう! - 14 まだまだ苦労じゃー...
Closureはまだまだ続くよ。かなり手強いのでじっくり取り組もう。

クロージャーは関数を変数のように扱う感じで理解しようとしているがちょっと違うような気もする。少しクロージャーを書くルールを覚える必要があるだろう。前回は引数を持たない関数の割り当てしか勉強しなかったが、今回は引数を持った関数の話。

Stringを繋げる関数connectionを書けば次のようになる。
func connection(a:String, b:String)->String {
return a + b
}

では、これをクロージャーで書くと次のようになる。
var connectionClosure:(String, String)->String = {
a, b in
return a + b
}
さて、初心者にとって、ここで「?????」が出てきて理解できないのが、「a」と「b]だ。何だこれは?ということになる。私も解ったわけではないが、Swift言語の凄いところは、この「a」と「b」を勝手にString型の引数として理解するそうだ。ということは,
var connectionClosure:(String, String)->String = {
p, q in
return p + q
}
これでもいいわけだ!理解できるかな?
もう一つ進むと、これを分離させることができる。
-----
2014年9月7日追記:この頃はクロージャを理解していなかったので、間違った解釈をしていた。クロージャは単なる「名前の無い関数」と思い込んでいたからだ。The Swift Programming Language本のクロージャーの説明にこうある。
プログラムコンテンツ内で既に定義された定数や変数をクロージャーは取り込んでリファレンス値を保持することができる。

ここで重要なのは既に定義された変数や定数が存在することで、強力な型推測(Inferring Type)機能が働いて省力ができるということだ。
-----

var connectionClosure:(String, String) -> String

connectionClosure = {
 p, q -> String in
return p + q
}

さらに省略できる。
connectionClosure = {
 p, q in p + q
}

もっと凄いのが、引数は指定しなくても決まったものがあるけど、それが$0、$1のように「$」という決まりごと。

すると、

connectionClosure = {
$0 + $1
}

ここまで省略ができてしまうと。この書き方を知らないと全く解らないだろう。忘れないように覚えとかないとね。

-----
2014年7月23日:Swiftで遊ぼう! - 15 苦労じゃーは続く
Closureの理解は未消化のままだな。以前読んだ内容がどんどん薄れていって言語体系を理解できなくなりそう(T_T)。今日の例文にはmethodが含まれる。hasPrefixとかhasSuffixってのがそれだ。いわゆる標準ライブラリで定義されているものなので、変更できないというか、使い方を理解していないと、意味がわからなくなる。例文の$0.hasPrefix($1)に示された$0は、最初の引数(String型)を示しており、「.」で繋がれたmethodのhasPrefixが作動するという意味になるのだろう。hasPrefixの引数がこのクロージャーで2番目のString型の引数にあたり、接頭語にこのキャラクターが含まれるのかどうか判断して、含まれたら「true」を返すということだ。

var including: (String, String, String) -> Bool = {
var JudgePre = $0.hasPrefix($1)
var JudgeSuf = $0.hasSuffix($2)
return JudgePre && JudgeSuf
}

including("Good + Bad", "Good","Bad")

この値は「true」ってことだけど解る?  


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

Swiftで遊ぼう! - 14 まだまだ苦労じゃー...

swift_logo2014年9月7日にクロージャに関する記事はまとめられて移動されました。→「クロージャ(Closures)は苦労じゃ」  


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

Swiftで遊ぼう! - 13 クロージャーで苦労じゃー!

swift_logo2014年9月7日にクロージャに関する記事はまとめられて移動されました。→「クロージャ(Closures)は苦労じゃ」