[英]Can I extend an existing class (e.g. String) with a custom trait in Scala?
考虑简单的特征TypeName
trait TypeName {
def typeName(): String
}
对于自定义类,我很清楚如何为typeName
方法指定我的实现。
class Point(val x: Int, val y: Int) extends TypeName {
def typeName(): String = {
"Point"
}
}
这现在允许我编写这样的函数
def printlnTypeName[T <: TypeName](value: T) = {
println(value.typeName());
}
但是,如果我想为标准库类提供此功能。 这样我就可以将String
、 Vector
或Array
传递给此printlnTypeName
函数并打印它们的类型名称!
我该怎么做?
OOP 方法是为标准库类引入包装器并使它们扩展特性
trait TypeName {
def typeName(): String
}
class Point(val x: Int, val y: Int) extends TypeName {
override def typeName(): String = "Point"
}
class StringHolder(value: String) extends TypeName {
override def typeName(): String = "String"
}
class VectorHolder[A](value: Vector[A]) extends TypeName {
override def typeName(): String = "Vector"
}
// class VectorHolder[A <: TypeName](value: Vector[A]) extends TypeName {
// override def typeName(): String = s"Vector[${value.head.typeName()}]"
// }
class ArrayHolder[A](value: Array[A]) extends TypeName {
override def typeName(): String = "Array"
}
def printlnTypeName[T <: TypeName](value: T) =
println(value.typeName())
FP 方式是引入一个类型类(这是一种更灵活的方式)
// type class
trait TypeName[A] {
def typeName(): String
}
object TypeName {
// instances
implicit val stringTypeName: TypeName[String] = () => "String"
implicit def vectorTypeName[A](implicit
aTypeName: TypeName[A]
): TypeName[Vector[A]] = () => s"Vector[${aTypeName.typeName()}]"
implicit def arrayTypeName[A](implicit
aTypeName: TypeName[A]
): TypeName[Array[A]] = () => s"Array[${aTypeName.typeName()}]"
}
class Point(val x: Int, val y: Int)
object Point {
implicit val pointTypeName: TypeName[Point] = () => "Point"
}
def printlnTypeName[T](value: T)(implicit tTypeName: TypeName[T]) =
println(tTypeName.typeName())
https://kubuszok.com/2018/implicits-type-classes-and-extension-methods-part-1/
https://tpolecat.github.io/2013/10/12/typeclass.html https://tpolecat.github.io/2015/04/29/f-bounds.html
https://books.underscore.io/shapeless-guide/shapeless-guide.html#sec:generic:type-classes (第 3.1 章)
https://www.baeldung.com/scala/type-classes
https://docs.scala-lang.org/scala3/book/types-type-classes.html
您可以使用现有的类型类:
// libraryDependencies += scalaOrganization.value % "scala-reflect" % scalaVersion.value
import scala.reflect.runtime.universe.{TypeTag, typeOf}
def printlnTypeName[T: TypeTag](value: T) =
println(typeOf[T])
要么
// libraryDependencies += "com.chuusai" %% "shapeless" % "2.3.10"
import shapeless.Typeable
def printlnTypeName[T: Typeable](value: T) =
println(Typeable[T].describe)
( def foo[T: TC](value: T)
是def foo[T](value: T)(implicit tc: TC[T])
的语法糖)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.