在某些用例中,创建对象的副本很有用,该对象是一组案例类的案例类的实例,它们具有共同的特定值.
例如,让我们考虑以下案例类:
case class Foo(id: Option[Int])
case class Bar(arg0: String, id: Option[Int])
case class Baz(arg0: Int, id: Option[Int], arg2: String)
Run Code Online (Sandbox Code Playgroud)
然后copy可以在每个案例类实例上调用:
val newId = Some(1)
Foo(None).copy(id = newId)
Bar("bar", None).copy(id = newId)
Baz(42, None, "baz").copy(id = newId)
Run Code Online (Sandbox Code Playgroud)
type Copyable[T] = { def copy(id: Option[Int]): T }
// THIS DOES *NOT* WORK FOR CASE CLASSES
def withId[T <: Copyable[T]](obj: T, newId: Option[Int]): T =
obj.copy(id = newId)
Run Code Online (Sandbox Code Playgroud)
所以我创建了一个scala宏,它完成了这项工作(几乎):
import scala.reflect.macros.Context
object Entity {
import …Run Code Online (Sandbox Code Playgroud) 我想编写一个Scala宏,它将一个case类的实例作为参数.可以传递给宏的所有对象都必须实现特定的标记特征.
以下代码段显示了标记特征和实现它的两个示例案例类:
trait Domain
case class Country( id: String, name: String ) extends Domain
case class Town( id: String, longitude: Double, latitude: Double ) extends Domain
Run Code Online (Sandbox Code Playgroud)
现在,我想使用宏编写以下代码,以避免运行时反射的严重性及其线程不安全:
object Test extends App {
// instantiate example domain object
val myCountry = Country( "CH", "Switzerland" )
// this is a macro call
logDomain( myCountry )
}
Run Code Online (Sandbox Code Playgroud)
宏logDomain在不同的项目中实现,看起来类似于:
object Macros {
def logDomain( domain: Domain ): Unit = macro logDomainMacroImpl
def logDomainMacroImpl( c: Context )( domain: c.Expr[Domain] ): c.Expr[Unit] = { …Run Code Online (Sandbox Code Playgroud) 我正在编写REST Web服务的包装器,我想要强类型的Scala API.
以下是我到目前为止所做的事情:
def getMentions(count: Option[Int] = None,
sinceID: Option[TweetID] = None,
maxID: Option[TweetID] = None,
trimUser: Option[Boolean] = None,
contributorDetails: Option[Boolean] = None,
includeEntities: Option[Boolean] = None) : List[Tweet] = {
val parameters = Map("count" -> count,
"since_id" -> sinceID,
"max_id" -> maxID,
"trim_user" -> trimUser,
"contributor_details" -> contributorDetails,
"include_entities" -> includeEntities)
/*
* Convert parameters, which is a Map[String,Any] to a Map[String,String]
* (Removing Nones) and pass it to an object in charge of generating the request. …Run Code Online (Sandbox Code Playgroud)