Когда использовать равняние, входят в систему объявление метода Scala?

Ваш код выдает ошибку в основном из-за того, что вы пытаетесь решить свою проблему с помощью неверного алгоритма. Тот факт, что JLS не допускает использование троичного в качестве условия в для цикла , также не помогает - но главная проблема в том, что вы упускаете правильное решение задачи.

Давайте начнем с общего утверждения, prematureOptimization == sqrt(sum(evil)) - сначала вы должны рассмотреть , что вы хотите сделать, а не , как это сделать или , почему код не работает.

  • цикл должен просто выполняться n раз, используя i в качестве счетчика.
  • Шаг i должен быть равен 1, если n равно> = 0, в противном случае -1

    ( примечание: если n является инвариантом (и он здесь) с использованием, например, abs (n) или n < 0 в условии, это плохая практика, хотя большинство компиляторов будет пытаться вычленить инвариант из цикла, обычно следует просто используйте временную переменную для хранения результата и вместо этого используйте результат в сравнении)

Итак, код под рукой должен быть:

void doSomething( int n ) {
  if ( n >= 0 )
    for( int i = 0; i < n; i++ )
      f( i, n );
  else
    for( int i = 0; i > n; i-- )
      f( i, n );
}

Факторинг из инвариантов и разделение отдельных ветвей кода - основные методы, используемые для повышения эффективности алгоритмов (не преждевременная оптимизация , обратите внимание); нет более быстрого и чистого способа сделать это. Некоторые могут возразить, что это случай разматывания петли - это очень хорошо было бы , если бы не тот факт, что эти две петли не должны быть намотаны вместе в первую очередь .. . [1 125]

Другое дело: третья операция в для цикла всегда была обычным оператором; давайте попробуем угадать , почему следующий код не компилируется?

0 <= n ? (i++) : (i--); // error: not a statement

... может быть, потому что следующий код тоже не скомпилируется?

0 <= n ? i : i; // error: not a statement

... и это по той же причине, что приведенный ниже код не будет работать и в Java?

i; // error: not a statement

Ваш ответ: ternary - это не утверждение - ternary просто возвращает значение и значение не является оператором ( по крайней мере в Java ); i++ и i-- разрешены в троичной форме только потому, что они возвращают значение , но они также вызывают побочные эффекты здесь.

84
задан Peter Mortensen 24 April 2013 в 17:51
поделиться

4 ответа

На самом деле я совершенно не согласен с Дэниелом. Я думаю, что неравный синтаксис никогда не должен использоваться . Если ваш метод представлен как API, и вы беспокоитесь о случайном возврате неправильного типа, добавьте явную аннотацию типа:

object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("Hello!")
    123
  }
}

Неравный синтаксис короче и может выглядеть «чище», но я думаю, что он просто добавляет возможность путаницы. Иногда я забывал добавить знак равенства и полагал, что мой метод возвращает значение, хотя на самом деле он возвращал Unit. Поскольку синтаксисы неравенства и равенства с предполагаемым типом визуально схожи, эту проблему легко упустить.

Хотя это требует от меня немного больше работы, я предпочитаю явные аннотации типов, когда они имеют значение (а именно , открытые интерфейсы).

105
ответ дан 24 November 2019 в 08:34
поделиться

ОБНОВЛЕНИЕ: начиная с Scala-2.10, использование знака равенства является предпочтительным. Старый ответ:

Методы, возвращающие Unit , должны всегда использовать синтаксис «не равно». Это позволяет избежать возможных ошибок при переносе реализации в API. Например, вы могли случайно сделать что-то вроде этого:

object HelloWorld {
  def main(args: Array[String]) = {
    println("Hello!")
    123
  }
}

Тривиальный пример, конечно, но вы можете видеть, как это может быть проблемой. Поскольку последнее выражение не возвращает Unit , сам метод будет иметь тип возврата, отличный от Unit . Это доступно в общедоступном API и может вызвать другие проблемы в будущем. С синтаксисом non-equals, не имеет значения, какое последнее выражение является последним, Scala фиксирует возвращаемый тип как Unit .

Он также очищает два символа. : -) Я также склонен думать, что синтаксис "не равно" упрощает чтение кода. Более очевидно, что рассматриваемый метод возвращает Unit , а не какое-то полезное значение.

В соответствующем примечании существует аналогичный синтаксис для абстрактных методов:

trait Foo {
  def bar(s: String)
}

Метод bar имеет подпись String => Unit . Scala делает это, когда вы опускаете аннотацию типа для абстрактного члена. Еще раз, это чище и (я думаю) легче читать.

Scala делает это, когда вы опускаете аннотацию типа для абстрактного члена. Еще раз, это чище и (я думаю) легче читать.

Scala делает это, когда вы опускаете аннотацию типа для абстрактного члена. Еще раз, это чище и (я думаю) легче читать.

41
ответ дан 24 November 2019 в 08:34
поделиться

Вы должны использовать знак равенства в объявлениях вызовов, за исключением определений, возвращающих Unit.

В последнем случае вы можете отказаться от знака равенства . Однако этот синтаксис может быть устаревшим, поэтому его лучше избегать. Использование знака равенства и объявление типа возврата всегда будет работать.

12
ответ дан 24 November 2019 в 08:34
поделиться

Одно: представьте последний оператор метода, который должен возвращать Unit, не возвращает Unit. Тогда использование неравного синтаксиса очень удобно, я надеюсь, что это не будет устаревшим, поскольку я вижу несколько вариантов его использования

0
ответ дан 24 November 2019 в 08:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: