Skip to content

Instantly share code, notes, and snippets.

@ezura
Last active August 15, 2019 02:34
Show Gist options
  • Save ezura/0817a85c50548f9e589a to your computer and use it in GitHub Desktop.
Save ezura/0817a85c50548f9e589a to your computer and use it in GitHub Desktop.
Swift2 全予約語 (82語) の解説 ref: https://qiita.com/ezura/items/610caef024cb5f956db7
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
switch (a) {
case 1:
printf("1\n");
case 2:
printf("2\n");
break;
default:
printf("default\n");
}
class Sample {
var member = 1
}
let a = Sample()
let b = a
a === b // -> true (指すものは同じ)
a.member = 2
b.member // -> 2
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
protocol SampleProtocol {
associatedtype AssociatedType // 付属型を宣言します
func sampleFunc(param :AssociatedType) -> AssociatedType
}
struct SampleStruct: SampleProtocol {
func sampleFunc(param: Int) -> Int { // 付属型が Int であると決定されます
return param + param
}
}
optionalSample: 1
optionalArraySample: 1
optionalArraySample: 2
optionalArraySample: 3
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
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)")
}
first loop: 0
second loop: 1
second loop: 2
second loop: 3
second loop: 4
second loop: 5
break firstLoop
finish: 5
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
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)")
optionalSample: 1
optionalArraySample: 1
optionalArraySample: 2
optionalArraySample: 3
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
func deferSample() {
defer {
print("in defer")
}
print("end of scope")
}
deferSample()
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
func deferSample() {
defer {
print("in defer")
}
print("end of scope")
}
deferSample()
end of scope
in defer
end of scope
in defer
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
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 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 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
do {...} while(...)
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
do {...} while(...)
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
do {...} while(...)
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
do {...} while(...)
func ifLetSample(value: Int?) {
if let a = value {
value is AnyObject! // => false
a is AnyObject! // => true (a はアンラップされています)
// 処理
}
// 処理
}
do {...} while(...)
while condition {
statements
}
switch (1, "a") {
case (1, "b"):
print("1, b")
case (1, _):
print("1, _") // ここがマッチします。 (_ はワイルドカード)
case (1, "a"):
print("1, a") // 上がマッチするので評価されません
}
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
switch (1, "a") {
case (1, "b"):
print("1, b")
case (1, _):
print("1, _") // ここがマッチします。 (_ はワイルドカード)
case (1, "a"):
print("1, a") // 上がマッチするので評価されません
}
while condition {
statements
}
repeat {
statements
} while condition
class A {}
let anyObj: AnyObject = A()
let a = anyObj as! A // AnyObject から A にキャスト
let v = 1 as Double
class SomeBaseClass {
required init() {}
}
class SomeSubClass: SomeBaseClass {
}
let someInstance: SomeBaseClass = SomeSubClass()
let runTimeInstance = someInstance.dynamicType.init()
runTimeInstance is SomeSubClass // -> true
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
Optional.None == nil // -> true
func sample(callback: () throws -> Int) rethrows {
try callback()
}
class Sample {
var a: Int?
func sampleMethod() -> Sample {
a = 1
return self // 自身 (playground 上では Sample と見えますが、プロパティ a が変更されているので上で作成したインスタンスだと確認できます)
}
}
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
1.self // -> 1
(1 + 1).self // -> 2
let expressionSample = 1
expressionSample.self // -> 1
class Sample {
var a: Int?
func sampleMethod() -> Sample {
a = 1
return self
}
}
let sample = Sample()
sample.sampleMethod() // sample 自身
sample.self.sampleMethod() // 上と同じになります。つまり、sample が評価された結果 = sample 自身が返ってきています
class Sample {
}
Sample.self // -> Sample.Type
Sample.self.init() // -> Sample のインスタンス (= Sample.self は自身の型を返しています)
infix operator ☁ {}
func ☁ (left: Int, right: Int) -> Int {
return left + right
}
1 ☁ 2 // => 3
infix operator ☁ {}
func ☁ (left: Int, right: Int) -> Int {
return left + right
}
1 ☁ 2 // => 3
indirect enum SampleEnum {
case Num(Int)
case IndirectNum(SampleEnum)
}
SampleEnum.IndirectNum(SampleEnum.IndirectNum(SampleEnum.IndirectNum(SampleEnum.Num(1))))
infix operator ☁ {}
func ☁ (left: Int, right: Int) -> Int {
return left + right
}
1 ☁ 2 // => 3
indirect enum SampleEnum {
case Num(Int)
case IndirectNum(SampleEnum)
}
SampleEnum.IndirectNum(SampleEnum.IndirectNum(SampleEnum.IndirectNum(SampleEnum.Num(1))))
enum SampleEnum {
case Num(Int)
indirect case IndirectNum(SampleEnum)
}
var value: Value { get nonmutating set }
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
postfix operator *** {}
postfix func *** (inout a: Int) -> Int {
a *= a
return a
}
var hoge = 4
hoge*** // => 16
var value: Value { get nonmutating set }
postfix operator *** {}
postfix func *** (inout a: Int) -> Int {
a *= a
return a
}
var hoge = 4
hoge*** // => 16
prefix operator *** {}
prefix func *** (inout a: Int) -> Int {
a *= a
return a
}
var hoge = 4
***hoge // => 16
let protocolMetatype: SampleProtocol.Protocol = SampleProtocol.self
prefix operator *** {}
prefix func *** (inout a: Int) -> Int {
a *= a
return a
}
var hoge = 4
***hoge // => 16
let protocolMetatype: SampleProtocol.Protocol = SampleProtocol.self
class Sample {
required init() {}
}
let metatype: Sample.Type = Sample.self
let instance = metatype.init()
switch (1, "a") {
case (1, "b"):
print("1, b")
case (1, _):
print("1, _") // ここがマッチします。 (_ はワイルドカード)
}
let a: Int
(a, _) = (0, 1)
a // -> 0
protocol SampleProtocol {
typealias AssociatedType // 付属型を宣言します
func sampleFunc(param :AssociatedType) -> AssociatedType
}
struct SampleStruct: SampleProtocol {
typealias AssociatedType = Int // 付属型の型を決めます
func sampleFunc(param: AssociatedType) -> AssociatedType {
return param + param
}
}
let a: Int
(a, _) = (0, 1)
a // -> 0
protocol SampleProtocol {
typealias AssociatedType // 付属型を宣言します
func sampleFunc(param :AssociatedType) -> AssociatedType
}
struct SampleStruct: SampleProtocol {
typealias AssociatedType = Int // 付属型の型を決めます
func sampleFunc(param: AssociatedType) -> AssociatedType {
return param + param
}
}
first loop: 0
second loop: 1
second loop: 2
second loop: 3
second loop: 4
second loop: 5
break firstLoop
finish: 5
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
protocol SampleProtocol {
typealias AssociatedType // 付属型を宣言します
func sampleFunc(param :AssociatedType) -> AssociatedType
}
struct SampleStruct: SampleProtocol {
typealias AssociatedType = Int // 付属型の型を決めます
func sampleFunc(param: AssociatedType) -> AssociatedType {
return param + param
}
}
first loop: 0
second loop: 1
second loop: 2
second loop: 3
second loop: 4
second loop: 5
break firstLoop
finish: 5
for var i = 0; i < 10; i++ {
// 処理
}
for i in 1...10 {
// 処理
}
for _ in 1...10 {
// 処理
}
func deferSample() {
let file = openFile("sample.txt")
defer { closeFile(file) } // 関数から抜ける時に閉じる
// 処理
}
deferSample()
(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)
let a = 1
switch a {
case 1:
print("1")
fallthrough
case 2:
print("2")
default:
print("default")
}
Sub Class's deinit is called
Super Class's deinit is called
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
}
}
}
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
^
*/
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 "何かもらいました"
}
}
class Sample {
var a: Int
init(_ param: Int) {
a = param
}
}
let sample = Sample(1)
class Sample {
var a: Int
init(param: Int) {
a = param
}
}
let sample = Sample(param: 1)
dynamic <#var | let #> <# name #>
struct SampleStruct {
var x = 0
mutating func modifyX(x: Int) {
self.x = x
}
mutating func reset() {
self = SampleStruct()
}
}
infix operator <#operator name#> {
precedence <#0 ~ 255#>
associativity <#left | right | none#>
}
func sample() {
return
}
var a = sample() // -> ()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment