假设我有这个:
val myAnon:(Option[String],String)=>String = (a:Option[String],defVal:String) => {
a.getOrElse(defVal)
}
不要介意该函数的作用。有没有办法让它变得通用,这样我就可以有一个选项[T]?
从这个答案中总结一下:不,你不能使 anonymous 函数变得通用,但你可以显式地将函数定义为扩展 Function0、Function1、Function2 等特征之一的类,并定义 apply 函数从这些特征中。那么你定义的类就可以是通用的。这是原始文章的摘录,可在此处:
scala> class myfunc[T] extends Function1[T,String] {
| def apply(x:T) = x.toString.substring(0,4)
| }
defined class myfunc
scala> val f5 = new myfunc[String]
f5: myfunc[String] = <function>
scala> f5("abcdefg")
res13: java.lang.String = abcd
scala> val f6 = new myfunc[Int]
f6: myfunc[Int] = <function>
scala> f6(1234567)
res14: java.lang.String = 1234
我不认为匿名函数可以有类型参数。有关详细信息,请参阅此答案。
14 年后...在 Scala 3.4 上
val function :
[A] => (Option[A], A) => A =
// I don't understand how the type inference works, but:
// You're gonna have to annotate the function on declaration
// just a tad ~~annoying~~
[A] => (a: Option[A], defaultValue: A) => a.getOrElse(defaultValue)
def method[A](a: Option[A], defaultValue: A): A =
function[A](a, defaultValue)
// ~~~> inferred
type GenericLambda = [A] => (A, A) => A
type ParameterizedType[A] = (A, A) => A
type TypeLambda = [A] =>> (A, A) => A
1 与其他人不同。
据我所知,2 和 3 是可以互换的,但我尝试使用参数化类型。当我需要大枪时,我会使用 lambda 类型,作为一种助记符。另请参阅:
上下文函数 (?=>
)• 依赖函数 • 匹配类型
class Example1(function: (Int, Int) => Unit) extends ((Int, Int) => Unit):
def defApply(a1: Int, a2: Int): Unit = function(a1, a2)
val valApply: (Int, Int) => Unit = function
// Invalid, write as [[Example3]] instead
class Example2(function: [A, R] => (A, A) => R) extends ([A, R] => (A, A) => R):
// -------------------------------------------------> ~~~~~~~~~~~~~~~~~~~~~~~
// | [A, R] => (x$1: A, x$2: A) => R is not a class type
def defApply[A, R](a1: A, a2: A): R = function(a1, a2)
val valApply: [A, R] => (A, A) => R = function
class Example3[A, R](function: (A, A) => R) extends ((A, A) => R):
def defApply(a1: A, a2: A): R = function(a1, a2)
val valApply : (A, A) => R = function
Example1((a, b) => println(s"a: $a, b: $b"))
Example3[Int, Unit]((a, b) => println(s"a: $a, b: $b"))
这只是为了强调该功能如何不能被滥用。