「Swift」の版間の差分
ナビゲーションに移動
検索に移動
(→環境) |
(→データ型) |
||
| 58行目: | 58行目: | ||
</pre> | </pre> | ||
| + | ==アクセス制御== | ||
==データ型== | ==データ型== | ||
*型の実体はインスタンス | *型の実体はインスタンス | ||
2021年2月20日 (土) 14:36時点における版
| Xcode | Mac | IPhone Xcode |
目次
環境
Xcode
コマンドライン
- swiftと入力
- 終了には、:q もしくは、ctrl+D
- パスが通ったところに配置されていれば実行できる
$ swift
Welcome to Apple Swift version 5.3.1 (swiftlang-1200.0.41 clang-1200.0.32.8).
Type :help for assistance.
1> print("test")
test
コマンドラインツールを実行
- アクティブ開発ディレクトリのコマンドラインツールを見つけて実行する
- アクティブ開発ディレクトリは、xcode-select で指定する
- アクティブ開発ディレクトリを表示
$ xcode-select -p /Applications/Xcode.app/Contents/Developer
- 以下のようにswiftコマンドを実行もできる
$ xcrun swift
SDK
- SDKを指定してswiftを起動するときに、指定できるSDK一覧を表示
$ xcodebuild -showsdks
iOS SDKs:
iOS 14.2 -sdk iphoneos14.2
iOS Simulator SDKs:
Simulator - iOS 14.2 -sdk iphonesimulator14.2
macOS SDKs:
DriverKit 20.0 -sdk driverkit.macosx20.0
macOS 11.0 -sdk macosx11.0
:
SDKを指定して、swiftを起動
$ xcrun -sdk macosx11.0 swift
環境変数にSDKパスを指定
- 以下でSDKのパスを取得し、SDKROOT環境変数に設定し、swiftを起動
$ xcrun -sdk macosx11.0 --show-sdk-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk
アクセス制御
データ型
- 型の実体はインスタンス
- 値型と参照型
- 基本データ型
- Int
- UInt
- Float
- Double
- Bool : true/false
- Character : Unicodeの1文字
- String : 値型
変数の定義
- 変数
var 変数名 : 型 = 式
var age : Int = 49
- 定数(単一代入)
let 変数名 : 型 = 式
let age = 49
型変換
- 暗黙の型変換は行われない
- Double() や Int() などのイニシャライザを利用する
1> var i:Int = 5 2> var d:Double = 0; 3> d = i error: repl.swift:3:5: error: cannot assign value of type 'Int' to type 'Double' 3> d = Double(i) 4> d $R0: Double = 5
文字列
- 連結は +
- リテラルは、"で囲む
- \n 改行など\でエスケープ
文字列埋め込み
- \(式) で展開される
> var i:Int = 5 i: Int = 5 > let s: String = "Number \(i * 3)" s: String = "Number 15"
配列
- T型の配列は、Array<T> もしくは、[T]
- 型省略初期化
> var ia = [1,2,3,4,5]
- 型宣言初期化
> var ia2: [Int] = [1,2,3,4,5]
- 要素0で初期化
> var sa = [String]() sa: [String] = 0 values
- もしくは
> var sa2: [String] = [] sa2: [String] = 0 values
参照と追加
> var ia = [1,2,3]
> ia[1]
$R0: Int = 2
> ia.append(4)
> ia
$R1: [Int] = 4 values {
[0] = 1
[1] = 2
[2] = 3
[3] = 4
}
map関数
- 元の配列内の全てのアイテムに対してアクションを行い結果に基づいた配列を作成
let base = [1,2,3]
let dbl = base.map {
(val) -> Int in
return val * 2
}
print(dbl)
結果:[2, 4, 6]
- 省略形
let base = [1,2,3]
let dbl = base.map({ $0 * 2 })
print(dbl)
結果:[2, 4, 6]
filter関数
- 元配列から条件に一致する配列を生成
let nums = [0,1,2,3,4,5,6]
print(nums.filter({ (num) -> Bool in
return num % 2 == 0
}))
結果:[0, 2, 4, 6]
- 省略形
let nums = [0,1,2,3,4,5,6]
print(nums.filter({ $0 % 2 == 0 }))
reduce関数
- 配列内の全ての値を単一の結果に集約
let nums = [1,2,3]
let initial = 10;
print(nums.reduce(initial, { (curTotal, val) -> Int in
return curTotal + val
}))
結果:16
- 省略形
let nums = [1,2,3]
let initial = 10;
print(nums.reduce(initial,{ $0 + $1 }))
結果:16
演算子
- C言語の演算子はほぼ使える
- ポインタはないため、*、&、-> は異なった意味
- インクリメント(++)、デクリメント(--) は廃止された
モジュールと名前空間
モジュールのインポート
- フレームワークや外部モジュールからクラスや関数情報をimportで取込む
- Xcodeにある、*.swiftdoc や *.swiftmodule がSwiftが利用できるモジュール情報
import Foundation
名前空間
- ドットで区切って修飾
制御構文
if
- 条件の()は不要
- 1文しかなくても{}は省略不可
- 条件はBool型である必要がある
if 条件 {
} else if 条件 {
} else {
}
for
for 変数 in コレクション {
}
整数のレンジ
- 開始値...終了値
for i in 0...10 {
print(i)
}
- 開始値..<終了値
for i in 0..<10 {
print(i)
}
for-in
- where以下は省略可能
for 定数 in 式 where 式 {
}
for i in 0 ... 10 where i % 2 == 0 {
print(i)
}
while
while 条件 {
}
repeat-while
repeat {
} while 条件
switch
- break不要
- 分岐に文字列や構造を持つ型も利用できる
- 列挙/範囲指定できる
- breakがなくてもcaseブロック終了でswitchを抜ける
- break書いても良い
- fall through は明示することで可能
- 式がとりうる値を網羅していないとコンパイルエラー
switch 式 {
case ラベルn:
文
default:
文
}
for i in 0 ... 10 {
switch i {
case 2, 4: // 列挙できる
print("twe,four\(i)") // breakがなくてもcaseブロック終了でswitchを抜ける
case 5:
print("five \(i)")
case 6:
break // break書いても良い
case 7 ..< 9: // 範囲指定
print("7 <= i < 9: \(i)")
fallthrough // fall through は明示することで可能
default: // 式がとりうる値を網羅していないとコンパイルエラー
print("other \(i)")
}
}
結果:
other 0
other 1
twe,four2
other 3
twe,four4
five 5
7 <= i < 9: 7
other 7
7 <= i < 9: 8
other 8
other 9
other 10
ラベル
- break はラベルのブロックを抜ける
- continue はラベルの次繰り返しへ
ループ
loop1: while 式 {
loop2: while 式 {
while 式 {
break loop1
continue loop1
break loop2
continue loop2
}
}
}
if switch
cond1: if 式 {
cond2: if 式 {
if 式 {
break cond2
}
break cond1
}
}
do
構造体
- structは値型
- プロトコルは、実装すべきメソッドやプロパティが定まっている
- 構造体の値を変更するメソッドは先頭に mutating を付与
struct 名前 : プロトコル{
変数・定数定義
イニシャライザ定義
メソッド定義
その他定義
}
- 例
- init() イニシャライザ
struct Person {
var name: String
var age: Int
init(name :String , age : Int) {
self.name = name
self.age = age
}
mutating func addAge(num: Int) {
self.age += num
}
}
struct Team {
let name: String
let members: [Person]
func printMembers(){
for member in members {
print("\(member.name) \(member.age)")
}
}
}
func test() {
var me = Person(name: "Yagi", age: 49)
me.addAge(num: 3)
print(me)
let team = Team(name:"family", members: [me])
team.printMembers()
}
test()
- 実行
$ swift struct.swift Person(name: "Yagi", age: 52) Yagi 52
クラス
class クラス名: スーパークラス, プロトコル {
var 変数: 型 = 初期値
init(引数: 型) {
super.init(引数)
self.変数 = 引数
}
func 関数(引数: 型) -> 戻り値の型 {
return 戻り値
}
}
- 例
class Person {
var name: String = ""
var age: Int = 0
init(name :String , age : Int) {
self.name = name
self.age = age
}
func addAge(num: Int) {
self.age += num
}
}
class Team {
let name: String = ""
var members: [Person] = []
func addMember(_ person: Person) {
self.members.append(person)
}
func printMembers(){
for member in members {
print("\(member.name) \(member.age)")
}
}
}
func test() {
let me = Person(name: "Yagi", age: 49)
me.addAge(num: 3)
print(me)
let team = Team()
team.addMember(me)
team.printMembers();
}
test()
- 結果
$ swift classes.swift classes.Person Yagi 52
列挙型
enum FoodChoice {
case cereal,salad,sandwich,pizza,chiken,pie
}
enum Meal {
case breakfast,lunch,dinner,snack
func foodChoices() -> [FoodChoice] {
switch self {
case .breakfast:
return [.cereal]
case .lunch:
return [.salad,.sandwich,.pizza]
case .dinner:
return [.sandwich, .pizza, .pie]
case .snack:
return [.cereal,.pie]
}
}
}
let meal: Meal = .lunch
print(meal.foodChoices())
結果:[__lldb_expr_29.FoodChoice.salad, __lldb_expr_29.FoodChoice.sandwich, __lldb_expr_29.FoodChoice.pizza]
関数
定義
func 関数名(引数名:型 = 初期値, ...) -> 戻り値型{
ステートメント
return 戻り値
}
import Foundation
// 関数定義
func goodmorning(name: String) -> String {
return "Good Morning \(name)!"
}
// return の省略、引数ラベルの別名
func hello(n name: String) -> String { "Hello \(name)!!" }
// 引数ラベルの省略
func goodbye(_ name: String) -> String { "Good-bye \(name)!!"}
// 関数定義 仮引数、戻り値は省略できる
func test() {
print(goodmorning(name:"Yagi"))
print(hello(n:"Hiroto"))
print(goodbye("Hiroto Yagi"))
}
test()
- 実行結果
$ swift main.swift Good Morning Yagi! Hello Hiroto!! Good-bye Hiroto Yagi!!
inoutによる参照渡し
- 引数のを値を変更する場合、inoutを付与
- 実引数を&を付与して渡す
import Foundation
func funcIntou(n: inout Int, m: inout Int) {
let temp = n
n = m
m = temp
}
func test() {
var a = 111;
var b = 999;
print(a, b)
funcIntou(n:&a, m:&b)
print(a, b)
}
test()
- 実行結果
$ swift func_inout.swift 111 999 999 111
プロパティ
構造体、列挙、クラスに定義可能
格納型プロパティ
- 定数、変数
計算型プロパティ
- 手続きで構成
var プロパティ名:型 {
get {
プロパティの値を返す文
}
set(仮引数) {
プロパティの値を更新する文
}
}
- 例
struct Tentimes {
var origin: Int
var ten: Int {
get {
return self.origin * 10
}
set(num) {
origin = num / 10
}
}
}
func test() {
var n = Tentimes(origin: 10)
print(n.ten)
n.ten = 10
print(n.origin)
}
test()
- 結果
$ swift property.swift 100 1
タイププロパティ/静的プロパティ
- 型に関連
- static を付与
プロパティオブザーバー
- プロパティの変更をトリガーに手続きを起動
- willSet:プロパティに格納される直前の値を、newValueで参照できる。willSet(仮引数) と具体的に引数を指定もできる
- didSet:プロパティに今まで格納されていた値を、oldValueで参照できる。didSet(仮引数) と具体的に引数を指定もできる
struct PropertyObserver {
var val:Int = 0 {
willSet {
print("new value:\(newValue)");
}
didSet {
print("old value:\(oldValue)");
}
}
}
func test() {
var po = PropertyObserver()
po.val = 1;
print("\(po.val)")
po.val = 2;
print("\(po.val)")
}
test()
- 実行
ew value:1 old value:0 1 new value:2 old value:1 2
添字付け
subscript(仮引数) -> 型 {
get {
添字で指定したプロパティを返す
}
set (仮引数) {
プロパティの値を変更する
}
}
- 実行
struct Upper {
var items:[String]
init(count: Int) {
self.items = Array(repeating:"", count:count);
}
subscript(pos: Int) -> String {
get {
return self.items[pos]
}
set {
self.items[pos] = newValue.uppercased()
}
}
}
func test() {
var u = Upper(count:3)
u[0] = "a"
u[1] = "b"
u[2] = "c"
print("\(u[0])\(u[1])\(u[2])")
}
test()
- 結果
$ swift subscript.swift ABC
タプル
let prof : (String, Double, Int) = ("Yagi", 173.0, 49)
print("\(prof.0) \(prof.1) \(prof.2)")
let (name, tall, age) = prof
print("name is \(name) \(tall) cm \(age) yo")
let prof2 = (name:"Yagi",tall:173.0, age:49)
print("name is \(prof2.name) \(prof2.tall) cm \(prof2.age) yo")
- 結果
Yagi 173.0 49 name is Yagi 173.0 cm 49 yo name is Yagi 173.0 cm 49 yo
SwiftUI
UIKitとのインターフェース
SwiftUIは既存のApplieプラットフォームUIフレームワークとシームレスに動作する。
MacOS
Playground
値の変化をグラフで見る
チュートリアル
© 2006 矢木浩人