回答編集履歴

4

修正

2018/08/29 05:50

投稿

xAxis
xAxis

スコア1349

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
- if let value = value { //① ロカル変数
29
+ let value = value //エラ
32
30
 
33
- print(value) //④ 100 メンバ変数ではなくローカル変数のvalueを指す
31
+ if let value = value {
34
32
 
35
- print(self.value) //⑥ Optional(100)
33
+ print(value) //
34
+
35
+
36
+
37
+ print(self.value)
36
38
 
37
39
  }
38
40
 
39
- print(value)//⓪ ローカル変数ではなくメンバ変数のvalueを指すOptional(100)
41
+ print(value)
40
42
 
41
43
  }
42
44
 
@@ -82,34 +84,54 @@
82
84
 
83
85
 
84
86
 
85
- AKTOさんのコメントにある
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-let構文の条件で宣言された定数```value```はif-let構文内のみでしか使用できません(⓪)。つまりif-let構文の条件にある定数```value```はローカル定数(変数)になります(①)。
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

追記&修正

2018/08/29 05:50

投稿

xAxis
xAxis

スコア1349

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) //Optional(100)
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

修正

2018/08/29 03:51

投稿

xAxis
xAxis

スコア1349

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

修正

2018/08/25 11:53

投稿

xAxis
xAxis

スコア1349

test CHANGED
@@ -56,7 +56,7 @@
56
56
 
57
57
 
58
58
 
59
- これはYesです。ただし質問に書かれてるInt?型のaは変数ではなく定数です。
59
+ これはYesです。ただし質問に書かれてるInt型のaは変数ではなく定数です。
60
60
 
61
61
 
62
62