北海道〜札幌〜
出張も無事終わり、帰りの飛行機の時間まで、しばらくあったので札幌を観光した。
お昼頃に札幌へ入ったので、お腹も空いていたので、あまり所持金のないお財布から奮発してウニ丼を食べた。約5000円也。
あら汁もついて、この値段。
正直言うと、5000円ほどの旨味は感じられなかったので、少しがっかりであった…
口溶けは滑らかで、変な癖はないが、甘味が強いわけでも旨味が強いわけでもなかったので少し物足りなかったのが、正直な感想である。今度は他の店にもトライしたいが、次来たときには貧乏になっていると思うので、いつトライできるかは分からない。
食べたあとに、近くの焼きホタテを食べた。500円也。
こちらは、この値段でこの大きさか!という意味ではとても満足だった。ホタテの肝(?)の部分の苦味もちょうどよかった。この値段でこの美味しさはオススメできる。
食べたあとに、駅に戻る最中、がっかりするらしい時計台を観に行った。
こちらは「がっかりするらしい」と思って観に行ったので、予想よりは「ちゃんと時計台だ」と思った。壁面のペンキが塗りたてなのか、とてもキレイで、長年ここにいるという貫禄は感じられなかったが…
雪も降り寒かったけど、北海道には一度住んでみたい。
関数とクロージャ part2 -Swift編-
さて、昨日投稿した記事の続きを書いていきたいと思います。
昨日投稿した記事は以下です。
関数を引数にする
Swiftでは、関数を引数にすることが出来ます。「どういうこと?!」と思う方もいらっしゃると思いますので、一先ずサンプルコードを御覧ください。
func nameMatch(list: [String], condition: (String) -> Bool) -> Bool { for item in list { if condition(item) { return true } } return false } func judgeName(name: String) -> Bool { if name == "John" { return true } return false } var members = ["Mike", "Eline", "John", "Kenny"] print(nameMatch(members, condition: judgeName))
このコードはnameMatchという関数に、membersという人物名の配列とjudgeNameという関数を引数として与えます。
すると、関数はnameMatch関数内でconditionという関数に置き換えられ、実行されます。各関数の簡単な挙動を説明すると。
nameMatch : 引数にnumbers(配列、String型)とjudgeName関数を取る。返り値はBool型(true、false)
judgeName : 引数にname(変数、String型)を取る。nameが"John"と一致すればtrue、一致しなければfalseを返す。返り値はBool型(true、false)
今日は時間が無くなったのでここまで。(この回、小刻みですみません) 今から飛行機に乗ります。
関数とクロージャ -Swift編-
今回は、関数とクロージャについて勉強します。
まず、関数とクロージャについてちょっとわからなかったので、調べてみました。
関数 関数とは、一般的に引数を与えると返り値が返ってくる物を言います。例えば、Name = "Mike"という引数を関数に与えると、"Hello Mike"と返す動作をするユニットのことを関数といいます。
クロージャ クロージャは、関数のインスタンスを作成した時に環境変数を与え実行される関数みたいなものをいいます。Appleは
Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures in Swift are similar to blocks in C and Objective-C and to lambdas in other programming languages.
述べています。
関数とクロージャ
関数
関数の定義には"func"を関数名に前置します。また、その後に"->"を使って返り値の型を定義します。以下に、サンプルコード作りました。関数の引数に、足し算をする数字を入れると足し算した値が返ってきます。
func plus(num1: Int, num2: Int) -> Int { return num1 + num2 } print(plus(1, num2: 2))
この場合、返り値の型はint、引数もそれぞれint型です。
ここで、注意しなくてはいけないのは引数2つめの引数は、引数名を添えなくてはいけないということです。なぜ、こういう仕組みにしたのかはよく分かりません(分かる方いらっしゃいましたら、教えていただけると幸いです)
実は、同じ方であれば以下の様な方法でも引数を定義することが出来ます。例えば
func sum(numbers: Int...) -> Int { var sum = 0 for number in numbers { sum += number } return sum } print(sum()) print(sum(42, 50, 10, 128))
のように、関数の引数として"numbers: Int..."とすることで、複数の引数(int型)を定義することが出来ます。個人的に、引数の個数を決定しなくていいところが便利かなって思いました。
関数に返り値を複数与える
Swiftでは返り値を複数にすることが簡単にできます。
また、引数に配列を入れることも可能です。まずは、サンプルコードを紹介したいと思います。
func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int, ave: Float) { var min = scores[0] var max = scores[0] var sum = 0 var ave: Float = 0 for score in scores { if score > max { max = score } else if score < min { min = score } sum += score } ave = Float(sum) / 5 return (min, max, sum, ave) } let statistics = calculateStatistics([5, 19, 66, 21, 3]) print(statistics.sum) print(statistics.2) print(statistics.ave)
基本的な関数の定義の仕方は、先述した通りです。
この中で
func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int, ave: Float)
の部分がミソですね。->(min: Int, max: Int, sum: Int, ave: Float)で返り値の型を定義しています。
関数内でゴニョゴニョ計算した後、次のように呼び出すことで返り値を得ることが出来ます。
let statistics = calculateStatistics([5, 19, 66, 21, 3]) print(statistics.sum) print(statistics.2) print(statistics.ave)
つまり、calculateStatisticsという関数で計算した内容をstatisticsに代入して、そのオブジェクトstatistics.sumであったり、statisticsの2番めの要素(ここでは、sumですね)statistics.2を呼び出すことで、該当の返り値を得ることが出来ます。
関数の入れ子(ネスト)
Swiftでも関数を入れ子にすることが出来ます。つまり、関数の中に関数を作る事ができます。
func increaseTen() -> Int { var y = 0; func add() { y += 10 } add() return y } print(increaseTen())
今回作成したコードはほんとうに意味がありませんが、increaseTenという関数の中にaddという関数があります。increaseTen関数が呼び出された時に中にあるadd関数も呼び出されます。
関数を返す
今まで書いた関数は first-class typeの関数で、関数を呼び出した時に関数を返すことが出来ます。(僕も、理解が追いついていないところがあります)
func halfNumber() -> ((Int) -> Float) { func half(number: Int) -> Float { return Float(number) / 2 } return half } var Half = halfNumber() print(Half(11))
このように、halfNumber関数を呼び出した時に、half関数を返します。つまりHalfはhalf関数と同義になるんですね。そうすると、Halfは関数となり引数を渡すとhalf関数で定義した処理が実行できるようになります。
今日はつかれたのでここまで。 何か、おかしいところやわからないところありましたら、コメントいただけると嬉しいです。
プログラムの実行フローを管理する -Swift編-
今回は、if文やfor文を使ってプログラムの実行フローを管理する方法を書きたいと思います。
参考にしたのはApple Inc.からiBooksを通じて提供されている"The Swift Programming Language (Swift2.1)"です。
for文
よく使われるループの文です。
var secondForLoop = 0 for var i = 0; i < 4; i++ { secondForLoop += i } print(secondForLoop)
ただ、このコードの中でのi++についてはSwift3で廃止予定のようですので、この記法はあまり薦められるものではないかもしれませんね。 今後これと同じコードを書こうと思えば、以下の様なコードを書きます。
var secondForLoop = 0 for i in 0..<4 { secondForLoop += i } print(secondForLoop)
この中の
for i in 0..<4
の部分が、先ほどの
for var i = 0; i < 4; i++
に当たります。スッキリ書けるようになりましたね。個人的な感想としては、Swiftは徹底的に";"を嫌っているようです。
for in
for inを使ったコードのサンプルを作ります。
let testScores = [75, 43, 100, 87, 12] var evaluation = 0 for score in testScores { if score > 45 && score < 61 { evaluation += 3 } else if score > 60 && score < 76 { evaluation += 4 } else if score > 75 && score < 91 { evaluation += 5 } else if score > 90 { evaluation += 6 } else { evaluation += 0 } } print(evaluation)
for in文はinの後に配列名を入れ、その要素を順に取り出すという役割を担います。取り出した要素は、ここではscoreという変数名に代入してfor in文内の処理に使います。 if文は、C言語などでは()でくくるのですが、swiftではくくる必要がありません。それ以外は、他の言語と変わりませんね。
if文
ここで、if文を扱いたいと思いますがその前に、optionalという型のような概念があるようです。これは、nilというCで言うとNULLのようなものを定義できる変数かを明記できる方法らしいです。
optional
一度使ってみます。以下に2つのサンプルプログラムを書きました。
var optionalString: String? = "Hello" print(optionalString == nil)
var optionalString: String? = "Hello" optionalString = nil print(optionalString == nil)
このコードを実行すると、上のコードはfalse下のコードはtrueという実行結果が返ってきます。
optional変数を明記する場合は、変数の型を明記するときに型の名前の後に"?"をつけます。これを行なうことで、nilを扱うことが出来ます。もしもこの"?"が無いとエラーが出ます。
if文の使い方
僕が個人的に使うif文の使い方は、if(条件式)という形態でswiftも基本的な記法は変わらないのですが、以下の使い方が初めてだったので、書き記しておこうと思います。
var optionalName: String? = "John Appleseed" var greeting = "Hello!" if let name = optionalName { greeting = "Hello, \(name)" print(greeting) }
このif文ではnameという変数にoptionalNameを代入できれば、つまりoptionalName != nilであればif文内の処理を実行するという意味になります。 試しに、以下のサンプルコードを実行してみると、出力されなくなります。
var optionalName: String? = "John Appleseed" var greeting = "Hello!" optionalName = nil if let name = optionalName { greeting = "Hello, \(name)" print(greeting) }
nilの判定条件式
nilであるかどうかを判定して、出力結果を操作する条件式があります。以下がサンプルコードになります。
let nickName: String? = nil let fullName: String = "Mike Seed" let informalGreeting = "Hi \(nickName ?? fullName)" print(informalGreeting)
このコードについて
(nickName ?? fullName)
が、判定のコードとなります。左のnickNameがnilであればfullNameを取るというものです。 つまり
``swift let nickName: String? = "Mike"
のように書き換えることで、実行結果はnickNameを取るようになります。 # switch文 次に、switch文について書きたいと思います。switch文は、与えられた変数や条件式が当てはまれば以下の実行を処理するという機能を持っています。今回のサンプルコードは、参考にしたテキストのコードを引用しています。
let vegetable = "red pepper" switch vegetable { case "celery": print("Add some raisins and make ants on a log.")
case "cucumber", "watercress":
print("That would make a good tea sandwich.")
case let x where x.hasSuffix("pepper"):
print("Is it a spicy \(x)?")
default:
print("Everything tastes good in soup.")
}
このコードの中に
case let x where x.hasSuffix("pepper"):
という文があります。これは、xについて末尾がpepperで終わっていた場合処理するという命令です。vegetable変数の中をいろいろ書き換えることで挙動を調べることが出来ます。 また、C言語などとは違いcaseの最後にbreakを入力する必要はありません。 # while・repeat文 これもまた、よく使うループですね。while文の条件式がtrueであれば中のプログラムをループ処理するというものです。
var n = 0
while n < 100 { n = n + 4 print(n) }
swiftでは、repeatという方法でもループが出来るようです。基本的にはwhileと同じなのですが、条件はスコープ({})の末に記します。
var n = 0
repeat { n = n + 4 print(n) } while n < 100 ``
for in, if文を使ったプログラム
これは、今回参考にしたDocumentに書かれていたプログラムに、僕自信が挙動を知るために適宜printを挿入しています。
let interestingNumbers = [ "Prime": [2, 3, 5, 7, 11, 13], "Fibonacci": [1, 1, 2, 3, 5, 8], "Square": [1, 4, 9, 16, 25], ] var largest = 0 for(kind, numbers) in interestingNumbers { print(String(kind) + "," + String(numbers)) for number in numbers { print(number) if number > largest { largest = number } } } print(largest)
コードの見方は、前述したとおりなのですがまず一番初めのfor in文で、interestingNumbersからkindに"Prime"や"Fibonacci"などのラベル(この場合はおそらく数列名)、numbersで配列を読み取ります。
その次のfor inでnumbersからnuberに一つずつの要素を代入します。後は、largestと比較し大きければlargestにnumberを代入するというプログラムです。
お問い合わせ
もしも「ここ、おかしいんじゃないかな」とか「よくわからない」という所があれば、記事にコメントいただけると嬉しいです。
変数の扱い方 -Swift編-
今回はSwiftにおける変数の扱い方について、自分の勉強ついでに備忘録的に書こうと思います。
参考にしたのは、Apple Inc.からiBooksを通して提供されているThe Swift Programming Language(Swift2.1)です。
使用環境はOS X El Capitan 10.11.6ですが、基本的にSwiftが動くXCodeがあれば動くと思います。
Swiftとは
SwiftはiOS、OSX、watchOS、tvOS向けのアプリケーションを開発するために作られたプログラム言語です。
参考にしたドキュメントには、簡単だのフレキシブルだの書いていますが、使ってみないとわからないので今回は省きます。
また、Automatic Reference Counting(ARC)にも対応しているようですが、これについても僕は無知なので省きます。
ウォーミングアップ
プログラムを書いたことが有る人なら、一度は通る"Hello World!"です。これは、printという関数を使用して"Hello World!"と出力させます。コードは以下のとおりです。
print("Hello World!")
実行結果は以下のようになります。
CやObjective-Cとは違い、以下の様な特徴があります。 * 各行のコードの最後に";"が要らない * main関数を定義する必要が無いこと * コードはグローバルスコープに書くこと
変数の扱い方
基本的な変数の扱い方
Swiftでは、型の指定・宣言は必須ではありません。例えばCでは
int varInt = 5; float varFloat = 12.3;
とするところをSwiftでは
var varInt = 5 var varFloat = 12.3
と書くことが出来ます。また、定数の宣言についてはCでは
const int varInt = 5;
のところを
let varInt = 5
と書くことが出来ます。定数は、一度定義すると後に書き換えることができない性質があります。
しかし、やはり「型を宣言しないと分からなくなる」という意見はごもっともですし、実は先に宣言した数値より後に代入した値のほうが精度が悪い場合、先に代入されたほうが優先されてしまう。なんてこともあります。
そこで、Swiftでは以下の様な方法で型を宣言することが出来ます。
var varInt: Int = 5 var varFloat: Float = 12.3
ここで、少し文字列の扱い方について説明をしたいと思います。2つの文字列を連結する場合、"+"演算子を利用して連結することが出来ます。以下がサンプルコードです。
var string1: String = "My name is " var string2: String = "Mike." print(string1 + string2)
これは、Javascriptなどでもよく使われている記法ですね。
以上が変数の基本的な使い方になります。
変数の型の変換
変数の型を変換して扱いたい場合はありますよね。その際に、場合に応じて2つの方法があります。
キャストする方法
C言語のように、変換した後に変数が持つ型(例えばintからfloatに変換したい場合はfloatのことを指します)を使って、変換したい変数をキャストすることで型の変換を行うことが出来ます。以下が、サンプルコードです。
let label1: String = "I am " var tall: Int = 170 let label2: String = " cm tall." print(label1 + String(tall) + label2)
int型のtallという変数をString()でキャストしてString型に変換して扱っています。もしも、Stringでキャストしなかった場合型が競合してエラーが発生します。
\と()を使う方法
文字列の中に違う型の変数を挿入したいときは、\と()を使用した方法が簡単です。なかなかイメージがつかないと思いますので、いかにサンプルコードとその実行結果を示します。
var tall: Int = 170 print("I am \(tall)cm tall.")
先ほどのキャストを使うより、簡単でわかりやすいと個人的に思うので、おすすめです。
配列
配列の使い方について、説明したいと思います。基本は、C言語とあまり変わりません。
var fruit: [String] = ["Apple", "Orange", "Grape", "Peach"] print(fruit[0]) var position: [String : String] = [ "Tsubasa" : "Captain", "Okada" : "FW", "Mizuno": "MF", ] print(position["Mizuno"]) position["Mitani"] = "GK" print(position["Mitani"])
実行結果は以下のようになります。
ここで、少し疑問なのは2行目、3行目の実行結果に"Optional"という文字が付いていること。少し調べてみたのですが、少し後にこの詳しい説明が書いているようなので次回に回したいと思います。もしも、読んでいくださっている人の中で解決策ご存知のかたおられましたら、コメントいただけると嬉しいです。
ちなみにですが、空の配列を用意したいということがあると思います。その場合は
let array = [String]() let dictionary = [String: Int]()
また、すでにある配列を空にしたい場合は。
fruit = [] fruit = [:]
と、書くことで定義することが可能です。
お問い合わせ
「ここおかしいんじゃないかな」「ここ、よくわからない」などありましたら、記事にコメントいただけると嬉しいです。もしも、コメントが難しい場合は、以下のメールアドレスにメールいただければと思います。
aki-kasi@a-dawn.net