簡體   English   中英

我可以在 Scala 中使用自定義特征擴展現有類(例如 String)嗎?

[英]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());
}

但是,如果我想為標准庫類提供此功能。 這樣我就可以將StringVectorArray傳遞給此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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM