Вот решение, которое не требует двух функций версии 1:
public class numberTower {
public static void main (String args[]) {
numberTower t = new numberTower(5);
System.out.println(t.numberTower (5));
}
static int c;
static int nn;
public numberTower (int n) {
nn = n;
c = 0;
}
String numberTower (int n) {
if (n < 1) return "";
String tower = "";
if (c < nn)
tower += numberTower (n - 1);
++c;
for (int i = n; i > 0; --i)
tower += Integer.toString(i);
tower += '\n';
if (c >= nn)
tower+=numberTower (n - 1);
return tower;
}
}
И версии 2:
public class numberTower {
public static void main (String args[]) {
numberTower t = new numberTower(5);
t.numberTower (5);
}
static int c;
static int nn;
public numberTower (int n) {
nn = n;
c = 0;
}
void numberTower (int n) {
if (n < 1) return;
String tower = "";
if (c < nn)
numberTower (n - 1);
++c;
for (int i = n; i > 0; --i)
System.out.print ("" + i);;
System.out.println();
if (c >= nn)
numberTower (n - 1);
}
}
Для предоставления примера кода скажите, что Вы хотите записать итератор, который ничего не возвращает, если источник является пустым или пустым.
public IEnumerable<T> EnumerateThroughNull<T>(IEnumerable<T> source)
{
if (source == null)
yield break;
foreach (T item in source)
yield return item;
}
Без повреждения урожая становится невозможно возвратить пустое множество в итераторе.
повреждение урожая указывает, что метод должен прекратить возвращать результаты. "возврат" отдельно не был бы достаточно хорош, или мог даже привести к ошибке, потому что тип возврата метода должен быть IEnumerable.
я не уверен, почему ключевое слово возврата также необходимо. Мое лучшее предположение было бы то, что это помогает сделать намерение оператора немного более ясным.
, Если Вам интересно, эта статья объясняет, что урожай делает негласно
урожая C#приведите к повреждению, и повреждение делают совершенно другие вещи! Посмотрите
for(int i = 0; i < 10; ++i) {
if(i > 5) { break; }
yield return i;
}
for(int v = 2710; v < 2714; v+=2) {
yield return v;
}
for(int s = 16; s < 147; ++s) {
if(s == 27) { yield break; }
else if(s > 17) { yield return s; }
}
, Вывод был бы IEnumerable этих значений: 0, 1, 2, 3, 4, 5, 2710, 2712, 18, 19, 20, 21, 22, 23, 24, 25, 26
Вот некоторый метод, который не делает ничего полезного, но это иллюстрирует, что можно объединить повреждение урожая и ворваться в тот же метод, и они делают две разных вещи! Повреждение просто убегает из цикла, повреждение урожая заканчивает метод полностью.
я предполагаю причину, возврат не используется, то, потому что Вы не возвращаете IEnumerable сами в методе. Кроме того, разве Вы не думаете, что повреждение урожая более ясно, чем возврат для этого вида повторяющейся ситуации? Я делаю лично.
Это недопустимо для использования return
оператор в блоке итератора. Кроме того, break
оператор мог служить двойной цели в блоке итератора, если бы нужно было позволить влиять на повторение: это могло использоваться для убегания из цикла или из переключателя, и это могло использоваться для убегания из целого повторения.
yield return
и yield break
и два ключевых слова в и себя, и они оба, кажется, необходимы.
У Вас должно быть различие между возвратом реализации IEnumerable, которая уже существует (возможно, Вы собираетесь возвратить Список), и анонимный итератор.
Вы не можете только использовать возврат или повредиться, потому что это - допустимые ключевые слова, которые могут использоваться для других целей. Вы также не можете использовать доходность своего собственного, потому что у Вас должен быть способ указать, возвращаете ли Вы объект в перечислении или заканчиваете перечисление, следовательно потребность в возврате урожая и повреждении урожая.
return
оператор используется для возвращения значения от функции.
, Если у Вас есть функция итератора как это:
public IEnumerable<int> IteratorOverInt() { }
оператор возврата в вышеупомянутой функции должен был бы возвратить заполненный IEnumerable<int>
.
public IEnumerable<int> IteratorOverInt() {
return new List<int> { 1, 2, 3, 4 };
}
, но если Вы работаете над функцией итератора, Вы будете использовать yield return
, таким образом, Ваш код мог бы быть похожим на это:
public IEnumerable<int> IteratorOverInt() {
for (int i = 0; i < 4; i++) {
yield return i;
}
}
Так yield return
возвращается int
, в то время как сигнатура метода требует IEnumerable<int>
, Что return
оператор выполнил бы в вышеупомянутом случае? Возвратить результаты, переопределяющие урожаи? Конкатенация безотносительно к урожаям? return
не имеет большого смысла в вышеупомянутом случае.
Таким образом нам нужен путь к [1 111], которые имеют смысл в блоке итератора, который является, почему существует yield break
.
, Конечно, можно ли сделать это с break
, но затем как Вы вышли бы из тела функции, если бы у Вас есть больше кода, это выполнилось бы? Перенести все в сложное если еще блок? Я сказал бы, что просто наличие yield break
будет лучше.