回答編集履歴
4
修正
test
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
|
13
13
|
|
14
14
|
|
15
|
-
let value: Int = 150
|
15
|
+
let value: Int = 150
|
16
16
|
|
17
17
|
|
18
18
|
|
@@ -20,23 +20,25 @@
|
|
20
20
|
|
21
21
|
|
22
22
|
|
23
|
-
let value: Int? = 100
|
23
|
+
let value: Int? = 100
|
24
|
-
|
25
|
-
let value: Int? = 200 //⑤ 名前衝突により宣言できない
|
26
24
|
|
27
25
|
|
28
26
|
|
29
27
|
init() {
|
30
28
|
|
31
|
-
|
29
|
+
let value = value //エラー
|
32
30
|
|
33
|
-
|
31
|
+
if let value = value {
|
34
32
|
|
35
|
-
print(
|
33
|
+
print(value) //
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
print(self.value)
|
36
38
|
|
37
39
|
}
|
38
40
|
|
39
|
-
print(value)
|
41
|
+
print(value)
|
40
42
|
|
41
43
|
}
|
42
44
|
|
@@ -82,34 +84,54 @@
|
|
82
84
|
|
83
85
|
|
84
86
|
|
85
|
-
|
87
|
+
>>tyobigorouさんのコメントを受けて修正します。
|
86
88
|
|
87
89
|
|
88
90
|
|
89
|
-
|
91
|
+
Swiftはオプショナルバインディング中でのシャドーイングが可能になっています。これは例外として出来ることで通常シャドーイングは出来ないようになっていそうです。もしかしたらやり方があるかもしれませんが自分の調べた結果ではオプショナルバインディング中のみでした。SwiftはHaskellに影響を受けていると聞いたことがあり、そのHaskellでもシャドーイングが可能です。そしてHaskellではシャドーイングが出来る範囲もSwiftよりも広いようです。
|
92
|
+
|
93
|
+
そしてそのシャドーイングの効果ですが代入する値を特定スコープ内で使えなくする、という効果です。だから上記の例でメンバ定数であるvalueはif-let構文のブロック中では直接呼び出せなくなっていてvalueを呼び出すとif-let構文の条件で宣言された定数valueが呼び出される、ということのようです。
|
90
94
|
|
91
95
|
|
92
96
|
|
93
|
-
|
97
|
+
### 余談
|
94
98
|
|
95
99
|
|
96
100
|
|
101
|
+
```swift
|
102
|
+
|
103
|
+
class Shadowing {
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
let value: Int? = 100
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
init() {
|
112
|
+
|
113
|
+
if let value = value {
|
114
|
+
|
115
|
+
print(value) // 100
|
116
|
+
|
117
|
+
let value = 150
|
118
|
+
|
119
|
+
print(value) //150
|
120
|
+
|
97
|
-
if
|
121
|
+
print(self.value) // Optional(100)
|
122
|
+
|
123
|
+
}
|
124
|
+
|
125
|
+
print(value) //Optional(100)
|
126
|
+
|
127
|
+
}
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
}
|
132
|
+
|
133
|
+
```
|
98
134
|
|
99
135
|
|
100
136
|
|
101
|
-
対して```init()```外に置かれたShadowクラスの定数```value```はメンバ定数(変数)です(②)。メンバ定数(変数)は基本的にクラス内で使われます(修飾子により外部でも、または内部だけで使うという風にすることも可能です)。
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
更にそのShadowクラスの外側に置かれた定数```value```はグローバル定数(変数)です(③)。グローバル定数(変数)はどこからでも呼び出せます(通常はローカル変数、メンバ変数、グローバル変数と言います)。
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
こ
|
137
|
+
何故かこれが許される・・・。
|
110
|
-
|
111
|
-
ただし上記の三つのタイプの変数のうち、任意のタイプの変数を宣言した時、その任意のタイプの変数名と同じ名前のものは使えません(⑤)。
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
if-let構文のローカルスコープ内でメンバ変数を扱いたい時には```self.value```のように```self```をつけます(⑥)。
|
3
追記&修正
test
CHANGED
@@ -6,9 +6,13 @@
|
|
6
6
|
|
7
7
|
|
8
8
|
|
9
|
+
|
10
|
+
|
9
11
|
```swift
|
10
12
|
|
11
13
|
|
14
|
+
|
15
|
+
let value: Int = 150 //③ グローバル変数
|
12
16
|
|
13
17
|
|
14
18
|
|
@@ -16,21 +20,23 @@
|
|
16
20
|
|
17
21
|
|
18
22
|
|
19
|
-
let value: Int? = 100
|
23
|
+
let value: Int? = 100 //② メンバ変数
|
24
|
+
|
25
|
+
let value: Int? = 200 //⑤ 名前衝突により宣言できない
|
20
26
|
|
21
27
|
|
22
28
|
|
23
29
|
init() {
|
24
30
|
|
25
|
-
if let value = value {
|
31
|
+
if let value = value { //① ローカル変数
|
26
32
|
|
27
|
-
print(value) //100
|
33
|
+
print(value) //④ 100 メンバ変数ではなくローカル変数のvalueを指す
|
28
34
|
|
29
|
-
print(self.value) // Optional(100)
|
35
|
+
print(self.value) //⑥ Optional(100)
|
30
36
|
|
31
37
|
}
|
32
38
|
|
33
|
-
print(value)
|
39
|
+
print(value)//⓪ ローカル変数ではなくメンバ変数のvalueを指すOptional(100)
|
34
40
|
|
35
41
|
}
|
36
42
|
|
@@ -69,3 +75,41 @@
|
|
69
75
|
|
70
76
|
|
71
77
|
なので勘違いはほとんどなく理解に問題ないんじゃないでしょうか。
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
(追記)
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
AKTOさんのコメントにある
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
> そういう文法だから
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
というのはスコープをもう少し説明をしておいた方が理解しやすいかもしれませんね。
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
if-let構文の条件で宣言された定数```value```はif-let構文内のみでしか使用できません(⓪)。つまりif-let構文の条件にある定数```value```はローカル定数(変数)になります(①)。
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
対して```init()```外に置かれたShadowクラスの定数```value```はメンバ定数(変数)です(②)。メンバ定数(変数)は基本的にクラス内で使われます(修飾子により外部でも、または内部だけで使うという風にすることも可能です)。
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
更にそのShadowクラスの外側に置かれた定数```value```はグローバル定数(変数)です(③)。グローバル定数(変数)はどこからでも呼び出せます(通常はローカル変数、メンバ変数、グローバル変数と言います)。
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
ここからが本題ですがある二つの定数が同一の名前で宣言された時、よりローカルな方を扱います(④)。グローバル変数>メンバ変数>ローカル変数の順によりローカルです。
|
110
|
+
|
111
|
+
ただし上記の三つのタイプの変数のうち、任意のタイプの変数を宣言した時、その任意のタイプの変数名と同じ名前のものは使えません(⑤)。
|
112
|
+
|
113
|
+
|
114
|
+
|
115
|
+
if-let構文のローカルスコープ内でメンバ変数を扱いたい時には```self.value```のように```self```をつけます(⑥)。
|
2
修正
test
CHANGED
@@ -56,7 +56,7 @@
|
|
56
56
|
|
57
57
|
|
58
58
|
|
59
|
-
これはYesです。ただし質問に書かれてるInt型のa
|
59
|
+
これはYesです。ただし質問に書かれてるInt型のaもInt?型のaも変数ではなく定数です。変数は```var```です。
|
60
60
|
|
61
61
|
|
62
62
|
|
1
修正
test
CHANGED
@@ -56,7 +56,7 @@
|
|
56
56
|
|
57
57
|
|
58
58
|
|
59
|
-
これはYesです。ただし質問に書かれてるInt
|
59
|
+
これはYesです。ただし質問に書かれてるInt型のaは変数ではなく定数です。
|
60
60
|
|
61
61
|
|
62
62
|
|