【问题标题】:Scala generics - type mismatch error when passing high order function as parameterScala泛型-将高阶函数作为参数传递时出现类型不匹配错误
【发布时间】:2017-03-10 03:04:48
【问题描述】:

我正在尝试将高阶泛型函数作为参数传递给另一个泛型函数。但是,我完全无法让它发挥作用。以下是我想要实现的示例代码。

def foo[T](data: Seq[T]) = {
    //some codes 
}

def bar[U](id: Sring, fn: Seq[U] => Unit) = {
    criteria match {
      case x => data:Seq[String] = //some data; 
                fn(data)
      case b => data:Seq[Int] = //some data; 
                fn(data)
      case c => data:Seq[Char] = //some data; 
                fn(data)
    }
}

bar("123", foo)

如果我运行代码,我会得到错误 - 类型不匹配 - 找到预期的 Seq[U] - Seq[String]

【问题讨论】:

    标签: scala


    【解决方案1】:

    val data 必须是U 类型,因为那是fn 的参数:

    def bar[U](id: Sring, fn: Seq[U] => Unit) = {
        val data: Seq[U] = //some data.
        fn(data) //I want U to be type of data i.e. Seq[String]
    }
    

    如果您希望U 成为String,则必须在调用bar 时指定它。

    bar[String]("123", foo)
    

    这是在运行时定义的,因此您无法在 bar 内部决定它应该具有的类型。如果您希望它始终是字符串,则只需删除 U

    【讨论】:

    • 如果 bar() 动态调用 fn() 会怎样?即可以根据条件将不同的数据类型序列传递给 foo() 例如Seq[String]、Seq[Int]、Seq[Char] 等,因为我已经更新了相关问题。
    • @RaKa 这是一个完全不同的问题。你需要一个类标签:stackoverflow.com/questions/5400394/… 你到底想达到什么目的?在我看来,如果没有泛型,您的代码可以大大简化
    【解决方案2】:

    bar 在其中使用特定类型 String 时是泛型没有意义。 fnSeq[U] => Unit,但您传递给它的是一个非常具体的 Seq[String]fn 仅在 U = String 时有效。如果fnSeq[Int] => Unit 会发生什么?类型不保证匹配。

    由于bar 的主体期望fn 接受Seq[String],你唯一能做的就是要求fn 成为Seq[String] => Unit

    def foo[T](data: Seq[T]) = data.foreach(println)
    
    def bar(id: String, fn: Seq[String] => Unit) = {
        val data: Seq[String] = List("a", "b", "c")
        fn(data)
    }
    
    scala> bar("123", foo)
    a
    b
    c
    

    【讨论】:

    • 如果 bar() 调用具有多种不同数据类型的 fn() 会怎样。例如正如你所说的 Seq[Int]?我们可以让它这样工作吗?因为,我在 bar 函数中有匹配条件,它根据条件生成不同的数据类型序列并调用 fn()。
    猜你喜欢
    • 2019-03-05
    • 1970-01-01
    • 1970-01-01
    • 2019-02-27
    • 2015-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多