LoginSignup
355
342

More than 3 years have passed since last update.

Swift2 全予約語 (82語) の解説

Last updated at Posted at 2015-12-03

Swift3 

Objective-C break  case  Objective-C 
( indirect )

調
使便

swift tutorial 



class, deinit, enum, extension, func, import, init, inout, internal, let, operator, private, protocol, public, static, struct, subscript, typealias, associatedtype, var, break, case, continue, default, defer, do, else, fallthrough, for, guard, if, in, repeat, return, switch, where, while, as, catch, dynamicType, false, is, nil, rethrows, super, self, Self, throw, throws, true, try, __COLUMN__, #column, __FILE__, #file, __FUNCTION__, #function, __LINE__, #line, _, associativity, convenience, dynamic, didSet, final, get, infix, indirect, lazy, left, mutating, none, nonmutating, optional, override, postfix, precedence, prefix, Protocol, required, right, set, Type, unowned, weak, willSet

 (declarations)


使

class



class 
(swift CC * )
class Sample {
    var member = 1
}

let a = Sample()
let b = a
a === b       // -> true (指すものは同じ)
a.member = 2
b.member      // -> 2

deinit

デストラクタの宣言をします。これは class でのみ有効です。(struct には実装できません)
スーパークラスの deinit はサブクラスの deinit 実行後に自動的に呼ばれます。

class SuperClass {
    deinit { print("Super Class's deinit is called") }
}

class SubClass: SuperClass {
    deinit { print("Sub Class's deinit is called") }
}

var subClass: SubClass? = SubClass()
subClass = nil
出力
Sub Class's deinit is called
Super Class's deinit is called

enum



extension



func



import



init



inout




class SampleClass {}

func inoutSampleForClass(inout sampleClass: SampleClass?) {
    sampleClass = nil
}

func withoutInoutSampleForClass(var sampleClass: SampleClass?) {
    sampleClass = nil
}

var sampleClass: SampleClass? = SampleClass()

// inout なし
withoutInoutSampleForClass(sampleClass)
sampleClass  // => SampleClass のインスタンス

// inout あり
inoutSampleForClass(&sampleClass)
sampleClass  // => nil
func inoutSample(inout a: Int) {
    a = 100
}

func withoutInoutSample(var a: Int) {
    a = 100
}

var varInt = 1

// inout なし
withoutInoutSample(varInt)
varInt // => 1

// inout あり
inoutSample(&varInt)
varInt // => 100

internal


 ()
()

: public, private

let



: var

operator



 iOS Developer Library  Language Reference > Lexical Structure > Operators 
: prefix, postfix, infix
prefix operator  {}
prefix func  (inout a: Int) -> Int {
    a *= a
    return a
}
postfix operator *** {}  // 複数文字列も可能
postfix func *** (inout a: Int) -> Int {
    a *= a
    return a
}
infix operator  {}
func  (left: Int, right: Int) -> Int {
    return left + right
}

var hoge = 2
hoge    // => 4
hoge***  // => 16
1  2    // => 3

private


 ()

: public, internal

protocol



public


 ()
() API 
: private, internal

static


static static 

struct



subscript


 [] 
Objective-C  [], {} 
実装例
class SubscriptSample {
    var hoge: AnyObject?
    subscript(index: Int) -> String {
        get {
            return "Int もらいました"
        }
        set {
            hoge = newValue
        }
    }

    subscript(index: String) -> String {
        get {
            return "String もらいました"
        }
        // setter なくても良いです
    }

    subscript(index: AnyObject?) -> String {
        return "何かもらいました"
    }
}
使用例
let subscriptSample = SubscriptSample()
var optionalSample: Int? = 1;
subscriptSample[3]     // => "Int もらいました"
subscriptSample["a"]   // => "String もらいました"
subscriptSample[nil]   // => "何かもらいました"
subscriptSample[optionalSample]  // => "何かもらいました"

typealias

型の別名を宣言

使用例
typealias IntAlias = Int
typealias Point = (Int, Int)

protocol 内で associated type (付属型) の宣言(Swift2.1まで)

Swift2.2 からは associatedtype がこの役割となります。この場面での typealias は Swift2.2 から警告、Swift3 から使用不可となります

protocol SampleProtocol {
    typealias AssociatedType           // 付属型を宣言します
    func sampleFunc(param :AssociatedType) -> AssociatedType
}

struct SampleStruct: SampleProtocol {
    typealias AssociatedType = Int  // 付属型の型を決めます
    func sampleFunc(param: AssociatedType) -> AssociatedType {
        return param + param
    }
}

参考:
The Swift Programming Language (Language Reference -> Declaration -> Type Alias Declaration)
The Swift Programming Language (Language Reference -> Declaration -> Protocol Associated Type Declaration)

associatedtype

(Swift2.2から)

associated type (付属型) の宣言をします。
(Swift2.1までは typealias の役割でした)

protocol SampleProtocol {
    associatedtype AssociatedType          // 付属型を宣言します
    func sampleFunc(param :AssociatedType) -> AssociatedType
}

struct SampleStruct: SampleProtocol {
    func sampleFunc(param: Int) -> Int {  // 付属型が Int であると決定されます
        return param + param
    }
}

: 
The Swift Programming Language (Language Reference -> Declaration -> Type Alias Declaration)
The Swift Programming Language (Language Reference -> Declaration -> Protocol Associated Type Declaration)

var



Keywords used in statements

break


switch 
for, while 
: document  Control Flow -> Labeled Statements
var i = 0
firstLoop: while true {
    print("first loop: \(i)")
    while true {
        print("second loop: \(++i)")
        switch i {
        case 5:
            print("break firstLoop")
            break firstLoop
        default:
            break
        }
    }
}
print("finish: \(i)")
first  loop: 0
second loop: 1
second loop: 2
second loop: 3
second loop: 4
second loop: 5
break firstLoop
finish: 5

関連: continue, fallthrough

case

列挙子リストの宣言、switch 文内で条件分岐、switch 文内以外で if, for との併用により、パターンマッチングができます。

let optionalSample: Int? = 1;
let optionalArraySample: [Int?] = [1, 2, nil, 3]

if case let x? = optionalSample {
    print("optionalSample:      \(x)")
}

for case let x? in optionalArraySample {
    print("optionalArraySample: \(x)")
}
optionalSample:      1
optionalArraySample: 1
optionalArraySample: 2
optionalArraySample: 3

参考:
Swift 2: Pattern Matching with “if case”,
The Swift Programming Language (Patterns -> Optional Pattern)
関連: enum

continue

次のループ処理へ移動します。
break と同様にラベルをつけることで移動するループ処理を指定することができます。

var i = 0
firstLoop: while true {
    print("first  loop: \(i)")
    if i != 0 { break }
    while true {
        print("second loop: \(++i)")
        switch i {
        case 5:
            print("continue firstLoop")
            continue firstLoop
        default:
            break
        }
    }
}
print("finish: \(i)")
first  loop: 0
second loop: 1
second loop: 2
second loop: 3
second loop: 4
second loop: 5
continue firstLoop
first  loop: 5
finish: 5

関連: break, fallthrough

default

switch 文内の条件分岐で、case に当てはまらなかった場合の処理の宣言をします。
関連: switch, case

defer

スコープを抜ける際に実行する処理を記述します。

func deferSample() {
    defer {
        print("in defer")
    }
    print("end of scope")
}
deferSample()
end of scope
in defer

ファイル読み込み処理などに有用とのこと(引用: The defer keyword in Swift 2: try/finally done right)

ファイル読み込みの例
func deferSample() {
    let file = openFile("sample.txt")
    defer { closeFile(file) } // 関数から抜ける時に閉じる

    // 処理
}
deferSample()

: 
The Swift Programming Language (Statements -> Defer Statement)
The defer keyword in Swift 2: try/finally done right

do



catchcatch
: catch, try

else


使
guard
: if, guard

fallthrough


switch  case 
swift break  case  swich 
fallthrough 
使用例
let a = 1
switch a {
case 1:
    print("1")
    fallthrough
case 2:
    print("2")
default:
    print("default")
}
C言語の場合(上記と同等の処理)
switch (a) {
case 1:
    printf("1\n");
case 2:
    printf("2\n");
    break;
default:
    printf("default\n");
}
1
2

for

下記の2種類の繰り返し構文を記述できます。

for
for var i = 0; i < 10; i++ {
    // 処理
}
for-in
for i in 1...10 {
    // 処理
}

for _ in 1...10 {
    // 処理
}

: in, while

guard


 else 
使guard 
func guardSample1(value: Int?) -> String {
    guard let value = value where value > 10 else {
            // この中では必ずスコープを抜ける処理を書きます
            return "in else block"
    }
    // ここからは value がアンラップされ、また、10 より大きいことが保証されます
    return "\(value)"
}

guardSample1(nil)  // => in else block
guardSample1(10)   // => in else block
guardSample1(100)  // => 100
func guardSample2(a: String, b: Int?) -> String {
    // 複数の変数・定数の評価もできます
    guard let intValue = Int(a), let b = b else {
        return "in else block"
    }
    // ここからは b がアンラップされます
    return "\(intValue + b)"
}

guardSample2("a", b: 1)    // => in else block
guardSample2("1", b: 1)    // => 2
guardSample2("1", b: nil)  // => in else block

: return, break, continue, throw

if


(true)
unwrap 使 Optional binding  ([Swift] Optional  Ver2) 
func ifLetSample(value: Int?) {
    if let a = value {
        value is AnyObject! // => false
        a is AnyObject!     // => true (a はアンラップされています)
        // 処理
    }
    // 処理
}

関連: else, guard

in

文脈によって下記のように意味が変わります。

  • クロージャのボディの開始箇所を表します
  • for ~ in の形で取り出す要素の配列を指定します

関連: for

repeat

C言語等の言語における

do {...} while(...)

 do
: while

return



2




 tuple


Swift @noreturn 
void  tuple 
空のtupleが返る例
func sample() {
    return
}
var a = sample() // -> ()

switch

条件分岐を行います。

switch (1, "a") {
case (1, "b"):
    print("1, b")
case (1, _):
    print("1, _")  // ここがマッチします。 (_ はワイルドカード)
case (1, "a"):
    print("1, a")  // 上がマッチするので評価されません
}

関連: case

where

マッチングの条件を追加します。

while

下記の2種類の繰り返し構文を記述できます。

while condition {
    statements
}
repeat {
    statements
} while condition

関連: repeat

Keywords used in expressions and types

as

大きく分けて、2 種類の役割があります。
* キャスト

class A {}
let anyObj: AnyObject = A()
let a = anyObj as! A  // AnyObject から A にキャスト
  • 型を明示すること
let v = 1 as Double

catch

例外が投げられた際にブロック内が実行されます。

dynamicType

実行時にインスタンスからメタタイプを取得します。

class SomeBaseClass {
    required init() {}
}
class SomeSubClass: SomeBaseClass {
}

let someInstance: SomeBaseClass = SomeSubClass()
let runTimeInstance = someInstance.dynamicType.init()
runTimeInstance is SomeSubClass // -> true

関連: Type, Protocol

false

Bool 型の値で偽を表します。

is

ある型またはあるプロトコルを実装した型として振る舞えるかどうかを検査します。

1 is Int             // -> true
(1, 1) is AnyObject  // -> false
(1, 1) is (Int, Int) // -> true

// プロトコルの検査
protocol SampleProtocol { }
class SampleClass: SampleProtocol { }

let sampleClassInstance = SampleClass()
sampleClassInstance is SampleClass      // true
sampleClassInstance is SampleProtocol   // true

nil

値が空であることを表します。

Optional.None == nil // -> true

rethrows

引数にとったクロージャが投げた例外をさらに投げます。

func sample(callback: () throws -> Int) rethrows {
    try callback()
}
class Sample {
    var a: Int?
    func sampleMethod() -> Sample {
        a = 1
        return self         // 自身 (playground 上では Sample と見えますが、プロパティ a が変更されているので上で作成したインスタンスだと確認できます)
    }
}

expression (式) に対して呼び出した場合、式がそのまま返ります

<#expression#>.self

(1 + 1).self の返り値は (1 + 1) という式と同等になりそうです。

式がそのまま返るとは
(1 + 1).self // (1 + 1)
余談
(1 + 1).self // 2 as Int ではない
// 証明
(1 + 1).self + 1.0 // OK
(1 + 1) + 1.0      // OK

let exp = 1 + 1    // 2 as Int
exp + 1.0          // Error (type mismatch)

type (型) に対して呼び出した場合、自身の型が返ります

<#type#>.self

class Sample {
}
Sample.self      // -> Sample.Type      

Sample.self.init() // -> Sample のインスタンス (= Sample.self は自身の型を返しています)

: The Swift Programming Language (Language Reference -> Expressions -> Postfix Self Expression)

Self



throw



throws



true


Bool 

try



__COLUMN__


__COLUMN__  (Int)
swift3  使

#column


#column  (Int)

__FILE__


__FILE__  (String)
swift3  使

#file


#file  (String)
swift2.2 使

__FUNCTION__


__FUNCTION__  (String)
swift3  使

#function


#function  (String)
swift2.2 使

__LINE__


__LINE__  (Int)
swift3  使

#line


#line  (Int)
swift2.2 使

使

associativity



3
  • left
  • right
  • none: 結合方向を指定しないため、優先度が同じ演算子同士を並べて使用することができなくなります。
演算子を定義する構文
infix operator <#operator name#> {
    precedence <#precedence level#>
    associativity <#left | right | none#>
}
同優先度、結合方向 none
infix operator *** {
    precedence 100
    associativity none
}
infix operator +++ {
    precedence 100
    associativity none
}
func *** (left: Int, right: Int) -> Int {
    return left * right
}
func +++ (left: Int, right: Int) -> Int {
    return left + right
}

1 +++ 1 *** 1
/*
    error: non-associative operator is adjacent to operator of same precedence
    1 +++ 1 *** 1
      ^
*/

関連: left, right, none, operator, precedence

convenience

init の前に記述することで、convenience initializer を宣言します。
関連: init

dynamic

Objective-C のランタイムを使用して値にアクセスします。

構文例
dynamic <#var | let #> <# name #>

didSet



final



get


computed property 

infix



infix operator  {}
func  (left: Int, right: Int) -> Int {
    return left + right
}

1  2    // => 3

: operator

indirect


使
:
indirect 

()
indirect enum SampleEnum {
    case Num(Int)
    case IndirectNum(SampleEnum)
}

SampleEnum.IndirectNum(SampleEnum.IndirectNum(SampleEnum.IndirectNum(SampleEnum.Num(1))))

indirect は列挙子の前に書いても良いです。

enum SampleEnum {
    case Num(Int)
    indirect case IndirectNum(SampleEnum)
}

詳細: Swift Programming Language (Enumerations -> Recursive Enumerations)

lazy

遅延評価します。

left

演算子を定義した際に、左結合を指定します。
詳細: このページの associativity 項
関連: associativity, operator, right, none

mutating

値型のオブジェクトにおいて、自身または自身のプロパティを書き換えるインスタンスメソッドに対して宣言する。

列挙体の場合
enum SampleEnum {
    case A, B, C
    case a, b, c
    mutating func upperCase() {
        switch self {
        case .a: self = .A
        case .b: self = .B
        case .c: self = .C
        default: break
        }
    }
}
構造体の場合
struct SampleStruct {
    var x = 0
    mutating func modifyX(x: Int) {
        self.x = x
    }
    mutating func reset() {
        self = SampleStruct()
    }
}

none



:  associativity 
: associativity, operator, right, left

nonmutating




使:
computed property  set  mutating iOS  API  setter  mutaing 使
var value: Value { get nonmutating set }

optional

プロトコルの実装を任意に指定します。

override

親クラスのメソッドやプロパティを上書きする際に宣言します。

postfix

独自の後置演算子を定義します。

postfix operator *** {}
postfix func *** (inout a: Int) -> Int {
    a *= a
    return a
}
var hoge = 4
hoge***  // => 16

関連: prefix, infix, operator

precedence

左右に被演算子をとる演算子の優先度 (0 ~ 255) を指定します。

演算子を定義する構文
infix operator <#operator name#> {
    precedence <#0 ~ 255#>
    associativity <#left | right | none#>
}
+++が先に評価される場合
infix operator *** {
    precedence 100
    associativity none
}
infix operator +++ {
    precedence 200
    associativity none
}
func *** (left: Int, right: Int) -> Int {
    return left * right
}
func +++ (left: Int, right: Int) -> Int {
    return left + right
}

1 +++ 1 *** 0  // => 0

関連: operator, associativity

prefix

独自の前置演算子を定義します。

prefix operator *** {}
prefix func *** (inout a: Int) -> Int {
    a *= a
    return a
}
var hoge = 4
***hoge  // => 16

関連: postfix, infix, operator

Protocol

Protocol のメタタイプを取得します。

let protocolMetatype: SampleProtocol.Protocol = SampleProtocol.self

: Type, dynamicType

required



 override required 

right



:  associativity 
: associativity, operator, left, none

set


computed property 

Type



class Sample {
    required init() {}
}

let metatype: Sample.Type = Sample.self
let instance = metatype.init()

: Protocol, dynamicType

unowned



weak 
nil 

: weak

weak



unowned  nil 

willSet


stored property 
: didSet

その他

_

ワイルドカード

switch (1, "a") {
case (1, "b"):
    print("1, b")
case (1, _):
    print("1, _")  // ここがマッチします。 (_ はワイルドカード)
}

関連: case

引数名の省略

引数が必要なinit
class Sample {
    var a: Int
    init(param: Int) {
        a = param
    }
}
let sample = Sample(param: 1)
引数が不要なinit
class Sample {
    var a: Int
    init(_ param: Int) {
        a = param
    }
}
let sample = Sample(1)

値を捨てる

let a: Int
(a, _) = (0, 1)
a // -> 0
355
342
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up

355
342