为什么 Scala 不从泛型类型参数推断类型? [英] Why scala doesn't infer type from generic type parameters?

查看:57
本文介绍了为什么 Scala 不从泛型类型参数推断类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设这个函数

def func[A](data: List[A], mapper: A => String) = { 
  data.map(item => mapper(item)) 
}

为什么这段代码不能编译:

Why this code doesn't compile:

val list = List(1, 2, 3)
func(list, a => a.toString)

但是这个可以:

val list = List(1, 2, 3)
func[Int](list, a => a.toString)

val list = List(1, 2, 3)
func(list, (a: Int) => a.toString)

虽然a 类型可以从IntList 列表中推断出来.为什么 Scala 不在这里推断类型?

While a type can be inferred from list which is List of Int. Why doesn't scala infer the type here?

还有什么办法吗?

推荐答案

还有另一种方法!它也碰巧产生了一些不错的语法糖:

There is another way! It also happens to make for some nice syntatic sugar:

def func[A](data: List[A])(mapper: A => String) = data map mapper

看起来像:

func(myList){
  case Left(one) => one
  case Right(_) => default
}

您无法获得类型信息以您期望的方式流动的原因是 Scala 中的类型信息是从左到右的.在其他系统中,类型信息是已知的,并且可以在定义它的地方推断其用途.有时您必须解决这些限制,但同时,在这种情况下,您可以使用看起来类似于您自己定义的控制结构的东西.

The reason that you can not get the type information to flow the way you'd expect is that type information in Scala is left to right. In other systems, type information is known and deduced for useage where it is defined. You sometimes have to work around these limitations but at the same time, in this case, you can get to work with something that looks akin to your own defined control structure.

所以...

func[Int]( //I've just told the typer what the information is and it can flow to the right.
func(list //the typer has to deduce the type and without a guide can not figure out what a => a.toString should be

这也是一个旧的问题",您可以在此处查看 SI-4773.

This is also an old "issue" you can see here SI-4773.

在评论中回复 Q:

如果你想要一个 Seq[A =>;B] 然后我会做一些类似于

If you want to have a Seq[A => B] then I'd do something similar to

func[A, B](data: List[A])(actions: A => B*) = actions map { 
  data map
}

使用可变参数(转换为 WrappedArray,因此是 map)来接受任何命令列表,以便您可以传递是

which is using varargs (translates to a WrappedArray, hence the map) to accept any list of commands so that you can pass is

func(list)(_.name, _.age, _.sex, _.stalker)

就提取和匹配您传入的内容而言:

as far as pulling out and matching on what you've passed in:

func[A, B](data: List[A])(actions: (String, A => B)*) = actions map { 
  case (name, f) => (name, data map f)
}

其中您使用 case 语句进行模式匹配并提取元组.

wherein you're using the case statement to pattern match and extract the tuple.

这篇关于为什么 Scala 不从泛型类型参数推断类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆