你在哪里拆分长Scala函数签名?

时间:2011-11-08 07:47:19

标签: scala coding-style

这样的定义
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 = {
    // ...
}

但是,鉴于我将不得不习惯其中一个,这会给我的队友带来最小的烦恼?

2 个答案:

答案 0 :(得分:19)

Scala style guide对此无话可说。事实上,它建议使用参数较少的方法: - )。

对于函数调用,它建议拆分,以便每个后续行与第一个括号对齐:

foo(someVeryLongFieldName,
    andAnotherVeryLongFieldName,
    "this is a string",
    3.1415)

就你个人而言,我会根据“保持在一起的事情”规则分开:

def foo[T <: Token[T]]
       (x: ArrayBuffer[T], y: T => ArrayBuffer[() => T])
       : (T, T, BigDecimal) = {
  // ...
}

因此参数在一行上,返回类型在一行上,类型限制在一行上。

答案 1 :(得分:5)

在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社区的关系如何。