Swift入門
code:swift version
$ swift --version
swift-driver version: 1.120.5 Apple Swift version 6.1 (swiftlang-6.1.0.110.21 clang-1700.0.13.3)
Target: arm64-apple-macosx15.0
code:Swiftの実行
$ swift main.swift
code:定数・変数.swift
let name: String = "John Doe" // 定数 JSのconstに相当
var age: Int = 30 // 変数 JSのlet, varに相当
JSのvar, letに似ている。letが定数なのが違和感あり。
code:型 基本.swift
let name: String
let age: Int
let bmi: Float
let is_student: Bool
let nickname: String?
ほとんど感覚通り
code:型 配列・辞書.swift
空辞書が[:]なのは独特な感じがする。
friends.isEmptyでBoolean返すみたいなこともできるらしい。
辞書でも、配列でもあらかじめメソッドが備わっている。
code: for文・if文.swift
for score in individualScores {
if score > 50 {
teamScore += 3
} else {
teamScore += 1
}
}
code:三項演算子的なもの.swift
let emote =
if age > 10 {
"🎉"
} else {
""
}
code:Range.swift
pythonでいうrange関数?直感的ではあるけど知らないとわからない。
code:関数.swift
func greet(person: String, day: String) -> String {
return "Hello \(person), today is \(day)."
}
greet(person: "Bob", day: "Tuesday")
呼び出す時はキーを指定して、呼び出す。宣言名はfunc
code:関数2.swift
func greet(_ person: String, on day: String) -> String {
return "Hello \(person), today is \(day)."
}
greet("John", on: "Wednesday")
on day: Stringのように引数名を別名にできる。関数内ではdayという変数で引数を受け取る時はonという引数名で渡せる。
引数をなくすこともできる。その場合は、_ を引数の頭につける
code:関数3.swift
func greet(_ person: String, name: String, _ day: String) -> String {
return "Hello \(person), today is \(day). \(name)"
}
print(greet("John", name: "aa", "Wednesday"))
無名引数の間に名称ありの引数を入れることもできる。
その場合は呼び出す際に順番を守る必要がある。
code:無名関数.swift
numbers.map({ (number: Int) -> Int in
let result = 3 * number
return result
})
{}で囲む必要がある。
code:class.swift
class Shape {
var numberOfSides = 0
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
}
var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()
// A shape with 7 sides.
code:class-init.swift
class NamedShape {
var name: String
init(name: String) {
self.name = name
}
}
self.nameを定義するなら、var name: Stringも定義しなければならない
pythonなら関数として定義するけど、initっていう独自の何かを使う。
code:class-extend.swift
class Square: NamedShape {
var sideLength: Double
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
}
override func simpleDescription() -> String {
return "A square with sides of length \(sideLength). \(name)"
}
}
継承も想像通り。
関数内でクラス変数を使うとき、selfを省略できる
code:class-getter-setter.swift
class EquilateralTriangle {
var sideLength: Double = 0.0
init(sideLength: Double) {
self.sideLength = sideLength
}
var perimeter: Double {
get {
return 3.0 * sideLength
}
set {
sideLength = newValue / 3.0
}
}
}
print(triangle.perimeter)
triangle.perimeter = 9.9
getterとsetterの実装。propetyと同じ要領。
setterにあるnewValueはどこから出現したかわからないが、変数名を変えるとエラーになるので必ずnewValueという名前を使う。
code:enum.swift
enum Animal {
case dog
case cat
case bird
}
Animal.dog
// dog
type(of: Animal.dog)
// Animal
Animal.dogでdogが返却されるのはよくわからない。でもAnimalインスタンスではあるみたい。
enumは曲者感あるので、別のページで深掘りする。
code:struct.swift
struct Card {
var rank: Rank
var suit: Suit
func simpleDescription() -> String {
return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
}
}
let threeOfSpades = Card(rank: .three, suit: .spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()
構造体
code:async-await.swift
func fetchUsername(from server: String) async -> String {
let userID = await fetchUserID(from: server)
if userID == 501 {
return "John Appleseed"
}
return "Guest"
}
非同期処理
asyncの位置が若干違う。
code:protocol.swift
protocol ExampleProtocol {
var simpleDescription: String { get }
mutating func adjust()
}
code:extend-protocol.swift
class SimpleClass: ExampleProtocol {
var simpleDescription: String = "A very simple class."
var anotherProperty: Int = 69105
func adjust() {
simpleDescription += " Now 100% adjusted."
}
}
var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription
struct SimpleStructure: ExampleProtocol {
var simpleDescription: String = "A simple structure"
mutating func adjust() {
simpleDescription += " (adjusted)"
}
}
var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription
classでもstructでも使える。
code:error-handring.swift
func send(job: Int, toPrinter printerName: String) throws -> String {
if printerName == "Never Has Toner" {
throw PrinterError.noToner
}
return "Job sent"
}
do {
let printerResponse = try send(job: 1040, toPrinter: "Bi Sheng")
print(printerResponse)
} catch {
print(error)
}
関数にthrowsの記述がある場合、do,tryのセットが必要。
try?とすることもできる。