函数接受任何类型,但“AnyVal”?

时间:2016-07-15 15:55:42

标签: scala

查看Akka docs以创建一个Actor:

  

当actor构造函数将值类作为参数时,不支持创建actor Props的推荐方法。

是否可以定义一个函数:

def anyTypeButValueClass[A : ...](x: A) = ???

其中A是除编译时的值类以外的任何类型吗?

我的理解是价值类扩展AnyVal,(按docs),但也有:

  

标准实现包括九个AnyVal子类型:

     

Double, Float, Long, Int, Char, Short, and Byte是数值类型。

     

Unit and Boolean是非数字值类型。

per AnyVal

如何编写此函数?

3 个答案:

答案 0 :(得分:6)

Scala type hierarchy显示Any分别有两种直接子类型,AnyRefAnyVal,分别用于参考和值类型。

这意味着您只需添加AnyRef约束:

def anyTypeButValueClass[A <: AnyRef](x: A) = ???

答案 1 :(得分:2)

&#34;接受任何类型,但AnyVal&#34;已在Enforce type difference得到解答,但它与&#34;非常不同;接受任何不扩展AnyVal&#34;的类型,这与&#34不同;接受除值类&#34;之外的任何类型。值类扩展AnyVal,但原始类型也是如此。

你可以这样做:

// just a marker trait
sealed trait NotAValueClass[A]

object NotAValueClass {
  implicit def AnyRefIsNotAValueClass[A <: AnyRef]: NotAValueClass[A] = new NotAValueClass[A] {}
  implicit val IntIsNotAValueClass: NotAValueClass[Int] = new NotAValueClass[Int] {}
  ... // same for other primitive types
}

def anyTypeButValueClass[A : NotAValueClass](x: A) = ...

答案 2 :(得分:1)

如果您愿意使用像shapeless这样的库,您也可以将其编码为

import shapeless._

def anyTypeButValueClass[A: |¬|[AnyVal]#λ](x: A) = x

参考:https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/package.scala#L54

示例:

@ def anyTypeButValueClass[A: |¬|[AnyVal]#λ](x: A) = x
defined function anyTypeButValueClass

@ anyTypeButValueClass(42)
Compilation Failed
Main.scala:296: ambiguous implicit values:
 both method nsubAmbig1 in package shapeless of type [A, B >: A]=> shapeless.<:!<[A,B]
 and method nsubAmbig2 in package shapeless of type [A, B >: A]=> shapeless.<:!<[A,B]
 match expected type shapeless.<:!<[Int,AnyVal]
anyTypeButValueClass(42)
                ^
@ anyTypeButValueClass("foo")
res0: String = "foo"