Swiftの基礎
import UIKit
// コメント
/*
複数行
コメント
*/
// 整数型
var i: Int = 123
// 浮動小数点型(倍精度)
var d: Double = 3.14
// 浮動小数点型(単精度)
var f: Float = 3.14
// 論理型
var flag : Bool = false
flag = true
// 文字列型
var s: String = "abc"
// 変数 (値を何度でも変更できる)
var a = 123
a = 456
// 定数 (いったん値を定義したら、その後変更できない)
let c1 = 42
//c1 = 1 // エラー
// セミコロンは複数行を1行につなげる時に使う。通常は必要なし
var a1 = 123; var a2 = 456
// 型の自動推論 (代入する値によって型が自動的に推論される)
let d1 = 70.0 // 右辺にDouble型のデータを書いたので、d1の型は自動的にDoubleと推論される。
// 変数の型を明示的に指定
let d2: Double = 70 // Intの70を与えているが、Doubleの70.0に変換される
let e1 = 94 // e1にはInt型の94が入る
//print("e1: " + e1) // "e1: "はString型、e1はInt型。型が異なるのでエラー。
// StringとStringを結合
print("e1: " + String(e1))
// C言語風にフォーマットを指定して表示
print( String(format: "%d %5.3f", 123, 3.14159) )
// 改行なしのprint
print("abc", terminator:"")
print("ABC", terminator:"")
// 文字列の結合
var name = "Swift" + " " + "Programming"
name += " Language"
//文字数のカウント
//name.characters.count -> obsolete
name.count
// printの文字列中で表示する変数を指定
let boyCount = 3
let girlCount = 5
print("There are \(boyCount) boys.")
print("There are \(girlCount) girls.")
// 配列
var colors : [String] = ["red", "black", "white", "blue"] // 要素の型を[]で囲う。
// var colors = ["red", "black", "white", "blue"] と書いても同じ
// 配列要素を添字により参照
colors[0] = "pink"
colors[1] = "pink"
// 空の配列 例:String型を入れる空の配列
colors = [String]()
// 配列要素の追加
colors.append("red")
colors.append("black")
colors.append("white")
colors.append("blue")
// 配列要素の削除
colors.remove(at: 2) // colors[2]が削除される
colors.removeAll() // 要素を全て削除
// 配列の要素数
colors.count
// 配列の要素をスキャンして処理
for c in colors { // スキャン中の要素はcに入る。
print(c)
}
// 多重配列
var array: [[Int]] = [[1,2,3],[4,5,6],[7,8,9]]
array[0][0]
array[2][1]
// ディクショナリ型
// キーと値のペアが格納される。キーを与えると、対応する値が検索される。
var petCounts = ["dog": 2, "cat": 3]
petCounts["dog"]
petCounts["cat"]
petCounts["dog"] = 123
petCounts["dog"]
// ディクショナリ型の要素数
petCounts.count
// キーをリストアップ
for k in petCounts.keys {
print("key = " + k)
}
// 値をリストアップ
for v in petCounts.values {
print("value = " + String(v))
}
// キーと値をリストアップ
for (pet, count) in petCounts {
print(pet + ":" + String(count))
}
// 以下のようにしてもディクショナリを宣言できる。
var wordCounts = Dictionary<String, Int>()
wordCounts["apple"] = 10
wordCounts["apple"]
// 関数
// 例 Intを2個受け取り、Intを1個返す関数
func add(a: Int, b: Int) -> Int {
return a + b
}
// 関数呼び出し。引数のラベルを指定する必要がある。
add(a: 1, b: 2)
// 例: 整数nまでの総和を求める。
func sum(n: Int) -> Int {
var s = 0
for i in 0...n { // nを含む
s += i
}
return s
}
// 関数呼び出し
sum(n: 10)
// 例: 再帰呼び出し
func recursiveSum(n: Int) -> Int {
if n == 0 {
return 0
} else {
return n + recursiveSum(n: n - 1)
}
}
recursiveSum(n: 10)
// 例: フィボナッチ数列
func fibonacci(n: Int) -> Int {
switch (n) {
case 1:
return 1
case 2:
return 1
default:
return fibonacci(n: n-2) + fibonacci(n: n-1)
}
}
// フィボナッチ数列を10項まで表示
for i in 1...10 {
print(fibonacci(n: i))
}
func rank(score: Double) -> String {
if score > 90 { // if (score > 90) { ... のようにカッコを書いても良い
return "A"
} else if score > 70 {
return "B"
} else {
return "C"
}
}
let score = 99
score > 90 ? "OK" : "NG" // 3項演算子。score>90が成立すれば"OK", 偽なら"NG"となる。
// 例: Stringを2個受け取り、Stringを1個返す関数
func createMessage(title: String, body: String) -> String {
return "title: \(title)\nbody: \(body)"
}
// 関数呼び出し
createMessage(title: "task", body: "mail John")
// 関数
func createMessage(optionalTitle: String?, optionalContent: String?) -> String? {
var message = ""
if (optionalTitle != nil) {
message += "title: " + optionalTitle! + "\n"
}
if let content = optionalContent {
message += "content: " + content
}
if message == "" {
return nil
} else {
return message
}
}
func messageCount(optionalMessages: Array?) -> Int? {
return optionalMessages?.count
}
func lastItem(items: Array?) -> Int? {
return items?[items!.count - 1]
}
func evaluate(diff: Int) -> String? {
switch diff {
case 100:
return "max"
case let x where 0 < x && x < 100:
return "up"
case 0:
return "-"
case let x where x < 0:
return "down"
default:
return nil
}
}
evaluate(diff: 56)
// 以下の文法は廃止された。
// var sum = 0
// for var i = 0; i < 3; ++i {
// sum += i
// }
var sum = 0
for i in 0..<3 { // 3 を含まない (0, 1, 2)
print(i)
sum += i
}
sum
sum = 0
for i in 0...3 { // 3を含む (0, 1, 2, 3)
print(i)
sum += i
}
sum
// while ループ
var x = 1
while x < 100 {
x = x * 2
}
// repeat..whileループ
var y = 1
repeat {
y = y * 2
} while y < 100
// do..while は廃止された。
//var y = 2
//do {
// y = y * 2
//} while y < 100
// タプルを返す
func getProfile() -> (name: String, age: Int, size: Double) {
return ("Steve", 46, 8.9)
}
let profile = getProfile()
print("name: " + profile.name)
// 可変個の引数
func squareSum(numbers: Int...) -> Int {
var sum = 0
func addSquare(x: Int) {
sum += x * x
}
for number in numbers {
addSquare(x: number)
}
return sum
}
squareSum(numbers: 4, 6, 8, 9)
// nを与えると、nより大きい場合にtrueを返す関数を返す
func greaterThanN(n: Int) -> ((Int) -> Bool) { // 1つの引数の場合は(Int)のように()が必要になった。
func gt(x: Int) -> Bool {
return n < x
}
return gt
}
// Intに関する条件とIntの配列を与えると、条件を満たす最初のIntを返す
func get1st(condition: ((Int) -> Bool), targets: [Int]) -> Int? {
for item in targets {
if condition(item) {
return item
}
}
return nil
}
let greaterThan5 = greaterThanN(n: 5)
let a3 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
get1st(condition: greaterThan5, targets: a3)
// クロージャ
// Int型のxをとり、2*x を返すクロージャとして返す。
var c = {(x:Int) -> Int in return 2*x}
c(123) // 関数呼び出し
// 次のようにも書ける。
// 1文の場合は、その値が返り値となる(returnを書く必要がない)。
c = {(x:Int) -> Int in 2*x}
c(123)
// $番号で引数を指定できる。
// "2"と書くことで$0と戻り値の型がIntであることが推論される。
c = {2 * $0}
// mapは配列に対し、その要素のそれぞれに、クロージャで指定される処理を適用する。
// 配列の値をそれぞれ2乗し、新たな配列を返す。
let numbers = [1,2,3,4]
numbers.map({
(x: Int) -> Int in
return x*x
})
// 配列の値にそれぞれ3をかけ、新たな配列を返す。
numbers.map({
n in 3*n
})
// 総和を求める。
// reduce(0)は和の初期値。$0はそれまでの累積値を表し、$1がスキャン中の要素を表す。
numbers.reduce(0) {
$0 + $1
}
// ソート (昇順) 新しい配列が返される。
var b = [1, 5, 3, 12, 2]
b.sort()
// ソート (昇順)
var b2 = b.sorted(by: {$0 < $1})
b2
// ソート (降順)
var b3 = b.sorted(by: {$1 < $0})
b2
// in-placeソート (元の配列の要素が変更を受ける)
b.sort{$0 < $1}
b
// 逆転
b.reverse()
// 値が配列に含まれているかをチェック。含まれていればtrueを返す。
b.contains(3)
// 検索
// 指定した値が配列内に見つかればインデックスを返す。
var k:Int? // オプショナル型。
k = b.firstIndex(of: 3) // 値3のインデックス2が値となる。
k = b.firstIndex(of: 1000) // 値1000は存在しないので、nilとなる。
2019.10.27