Где вы разделяете длинные сигнатуры функций Scala?
Определение типа
def foo(x: Int) = x + 1
приятный и короткий и выглядит красиво, но когда сама подпись становится неудобной,
def foo[T <: Token[T]](x: ArrayBuffer[T], y: T => ArrayBuffer[() => T]): (T, T, BigDecimal) = {
// ...
}
Я не знаю, где его разделить. Я считаю, что все следующее выглядит неудобно:
def foo(
x: Int,
y: Int
): Int = {
// ...
}
def foo(
x: Int,
y: Int
): Int =
{
// ...
}
def foo(
x: Int,
y: Int
): Int
= {
// ...
}
def foo(
x: Int,
y: Int
):
Int = {
// ...
}
Но, учитывая, что мне придется привыкнуть к одному из них, что вызовет наименьшее раздражение моих товарищей по команде?
Ответы
Ответ 1
Scala руководство по стилю не имеет права говорить об этом. На самом деле он рекомендует использовать методы с меньшим количеством параметров: -).
Для вызовов функций он рекомендует разделять так, чтобы каждая последующая строка выравнивалась с первой скобкой:
foo(someVeryLongFieldName,
andAnotherVeryLongFieldName,
"this is a string",
3.1415)
Лично в вашем случае я бы разделился по правилу "держать как вместе":
def foo[T <: Token[T]]
(x: ArrayBuffer[T], y: T => ArrayBuffer[() => T])
: (T, T, BigDecimal) = {
// ...
}
Итак, параметры находятся в одной строке, тип возврата - в одной строке, а ограничение типа - в одной строке.
Ответ 2
В Haskell длинные сигнатуры часто записываются таким образом:
someFunc :: (Some Constraints Go Here)
=> Really Long Arg1 Type
-> Really Long Arg2 Type
-> Really Long Result Type
somefunc x y = ...
Чтобы перевести этот Haskellism в Scala,
def foo [ T <: Token[T] ]
( x : ArrayBuffer[T]
, y : T => ArrayBuffer[() => T]
) : (T, T, BigDecimal) = {
// ...
}
Вот как я это сделаю. Не знаете, как кошерно это с сообществом Scala.