回答編集履歴
3
誤記訂正
test
CHANGED
@@ -152,7 +152,7 @@
|
|
152
152
|
|
153
153
|
```
|
154
154
|
|
155
|
-
(1)が典型的な使い方ですが、これではUpdateの1回の呼び出しで1世代のみを取り出すことができません。そこで(2)の方法に着目します。(2)なら「まだ次の要素があるかをMoveNext()で調べ、もしあるならその要素をCurrentでアクセスする」というのをUpdateの中で1回だけ行えます。(A)はIEnumerableの計算を開始するためのコードのため上の例ではStartに
|
155
|
+
(1)が典型的な使い方ですが、これではUpdateの1回の呼び出しで1世代のみを取り出すことができません。そこで(2)の方法に着目します。(2)なら「まだ次の要素があるかをMoveNext()で調べ、もしあるならその要素をCurrentでアクセスする」というのをUpdateの中で1回だけ行えます。(A)はIEnumerableの計算を開始するためのコードのため上の例ではStartに置きましたが、なんども繰り返しGAを実行したいなら、適当なタイミングで(Startメソッド以外の場所で)
|
156
156
|
|
157
157
|
`generator = GA().getEnumerator();`
|
158
158
|
|
2
誤記訂正
test
CHANGED
@@ -114,7 +114,11 @@
|
|
114
114
|
|
115
115
|
---
|
116
116
|
|
117
|
-
補足:上のコードが少々わかりにくかったかも知れませんね。コルーチンで実装されたジェネレーターの典型的な使い方はforeachでの利用なのですが、それと対比すると理解しやすいかも知れません。
|
117
|
+
補足:上のコードが少々わかりにくかったかも知れませんね。コルーチンで実装されたジェネレーターの典型的な使い方はforeachでの利用なのですが、それと対比すると理解しやすいかも知れません。
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
IEnumerator<T>はT型の要素を列挙する能力を持つ型です。(foreachなどを使うとこの型を直接目にしないため見慣れないかも知れません)。またIEnumerable<T>というのはIEnumerator<T>を生成する能力がある型で大抵のコレクション型(配列, List, Dictionaryなど)はこのインターフェースを備えています。(これはUnityの仕様ではなくC#の標準ライブラリーの仕様です)
|
118
122
|
|
119
123
|
|
120
124
|
|
1
補足
test
CHANGED
@@ -109,3 +109,47 @@
|
|
109
109
|
|
110
110
|
|
111
111
|
コルーチンの動きが実感できてくると「単純なループ構造で書かれた関数を、データを次々と生み出すもの(ジェネレーター)として利用できる」「独立したプログラムの流れを複数並行して動かすことができる=>スレッドを生成せずにスレッド的な動きにできる」といった応用が見えてくると思います。
|
112
|
+
|
113
|
+
|
114
|
+
|
115
|
+
---
|
116
|
+
|
117
|
+
補足:上のコードが少々わかりにくかったかも知れませんね。コルーチンで実装されたジェネレーターの典型的な使い方はforeachでの利用なのですが、それと対比すると理解しやすいかも知れません。IEnumerable<T>というのはT型のデータを列挙するものとして捉えてください。(これはUnityの仕様ではなくC#の標準ライブラリーの仕様です)
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
```C#
|
122
|
+
|
123
|
+
IEnumerable<T> GetGenerator() { ... }
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
//(1) foreachで利用する方法
|
128
|
+
|
129
|
+
foreach (T element in GetGenerator()) {
|
130
|
+
|
131
|
+
... elementに対する処理 ...
|
132
|
+
|
133
|
+
}
|
134
|
+
|
135
|
+
|
136
|
+
|
137
|
+
//(2) 上記と同じことを別の書き方で書くと
|
138
|
+
|
139
|
+
IEnumerator<T> enumerator = GetGenerator().getEnumerator(); // (A)
|
140
|
+
|
141
|
+
while (enumerator.MoveNext()) { // (B)
|
142
|
+
|
143
|
+
T element = enumerator.Current;
|
144
|
+
|
145
|
+
... elementに対する処理 ...
|
146
|
+
|
147
|
+
}
|
148
|
+
|
149
|
+
```
|
150
|
+
|
151
|
+
(1)が典型的な使い方ですが、これではUpdateの1回の呼び出しで1世代のみを取り出すことができません。そこで(2)の方法に着目します。(2)なら「まだ次の要素があるかをMoveNext()で調べ、もしあるならその要素をCurrentでアクセスする」というのをUpdateの中で1回だけ行えます。(A)はIEnumerableの計算を開始するためのコードのため上の例ではStartに起きましたが、なんども繰り返しGAを実行したいなら、適当なタイミングで(Startメソッド以外の場所で)
|
152
|
+
|
153
|
+
`generator = GA().getEnumerator();`
|
154
|
+
|
155
|
+
とすれば何度でも新たな列挙をやりなおせます。
|