【问题标题】:Defining partial function with variable arguments in Scala在 Scala 中使用可变参数定义偏函数
【发布时间】:2015-06-26 22:27:58
【问题描述】:

我正在尝试定义一个通用的验证框架。我正在考虑使用部分函数来定义规则并将它们传递给通用函数以评估并返回结果。代码如下所示:

  def assert(name: TField, validator: PartialFunction[(Any*), String], input: Any*): Seq[ValidationError] = {
    if (validator.isDefinedAt(input)) {
      invalidInput(name.name, validator(input))
    } else {
      Seq.empty
    }
  }

  assert(fieldA, hasValidValue, inputValue, allowedValues)
  assert(fieldB, isPositive, input)

  // =-=-=-=--=-=-= Validation Rules =-=-=-=-=-=-=-=
  def hasValidValue[T] = PartialFunction[(T, Set[T]), String] {
    case (input, validValues) if !validValues.contains(input) => "Value not allowed"
  }

  def isPositive = PartialFunction[Long, String] {
    case value: Long if value <= 0 => "Value should always be positive"
  }

但我不知道如何在这一行定义带有可变参数的偏函数参数:

  def assert(name: TField, validator: PartialFunction[(Any*), String], input: Any*): Seq[ValidationError] = {

因此,即使上面的定义编译得很好,但在实际尝试调用 assert 时还是会出现编译器错误:

// Error: Type mismatch, Expected: ParitalFunction[Any, String], Found: PartialFunction[(Nothing, Set[Nothing]), String]
  assert(fieldA, hasValidValue, inputValue, allowedValues)

// Error: Type mismatch, Expected: ParitalFunction[Any, String], Found: PartialFunction[Long, String]
  assert(fieldB, isPositive, input)

那么我该如何定义呢?

【问题讨论】:

    标签: scala scala-2.10


    【解决方案1】:

    您只需将PartialFunction[(Any*), String] 更改为PartialFunction[Seq[Any], String]。这是因为可变参数 input 变成了 Seq[List],而这正是验证器实际接收的内容。

    更新

    这是一个关于可变参数如何工作的演示:

    case class TField(name: String)
    type ValidationError = String
    def invalidInput(s: String, v: String): Seq[String] = Seq(v)
    
    def assert(name: TField, validator: PartialFunction[Seq[Any], String], input: Any*): Seq[ValidationError] = {
      if (validator.isDefinedAt(input)) {
        invalidInput(name.name, validator(input))
      } else {
        Seq.empty
      }
    }
    
    def isPositive = PartialFunction[Seq[Any], String] {
      case value if value.length < 2 => "Value need to have at least 2 values"
      case _ => "Ok"
    }
    
    assert(TField("s"), isPositive, 5L)
    assert(TField("s"), isPositive, "s1", 1, -2L, "s3")
    

    【讨论】:

    • 将 Any* 更改为 Seq[Any] 后会出现类似的错误。错误:类型不匹配,预期:ParitalFunction[Seq[Any], String],找到:PartialFunction[(Nothing, Set[Nothing]), String]。我认为问题在于将不同的规则函数参数(如 hasValidValue[T] = PartialFunction[(T, Set[T]), String])映射到断言函数的参数(PartialFunction[(Any*), String])。
    • 查看更新的答案。如果是关于打字,那么可能是一个单独的问题。这个问题是关于可变参数的。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多