假设我有很多类似的数据类.这是一个示例类User,定义如下:
case class User (name: String, age: Int, posts: List[String]) {
val numPosts: Int = posts.length
...
def foo = "bar"
...
}
Run Code Online (Sandbox Code Playgroud)
我感兴趣的是自动创建一个方法(在编译时),Map该方法以在运行时调用每个字段名称时将其映射到其值的方式返回.对于上面的例子,让我们说我的方法被调用toMap:
val myUser = User("Foo", 25, List("Lorem", "Ipsum"))
myUser.toMap
Run Code Online (Sandbox Code Playgroud)
应该回来
Map("name" -> "Foo", "age" -> 25, "posts" -> List("Lorem", "Ipsum"), "numPosts" -> 2)
Run Code Online (Sandbox Code Playgroud)
你会如何用宏来做到这一点?
这就是我所做的:首先,我创建了一个Model类作为我所有数据类的超类,并在那里实现了这样的方法:
abstract class Model {
def toMap[T]: Map[String, Any] = macro toMap_impl[T]
}
class User(...) extends Model {
...
}
Run Code Online (Sandbox Code Playgroud)
然后我在一个单独的Macros对象中定义了一个宏实现: …
感谢上一个问题的答案,我能够创建一个函数宏,使得它返回一个Map将每个字段名称映射到它的类值,例如
...
trait Model
case class User (name: String, age: Int, posts: List[String]) extends Model {
val numPosts: Int = posts.length
...
def foo = "bar"
...
}
Run Code Online (Sandbox Code Playgroud)
所以这个命令
val myUser = User("Foo", 25, List("Lorem", "Ipsum"))
myUser.asMap
Run Code Online (Sandbox Code Playgroud)
回报
Map("name" -> "Foo", "age" -> 25, "posts" -> List("Lorem", "Ipsum"), "numPosts" -> 2)
Run Code Online (Sandbox Code Playgroud)
这就是生成Tuples的Map地方(见Travis Brown的回答):
...
val pairs = weakTypeOf[T].declarations.collect {
case m: MethodSymbol if m.isAccessor =>
val name = c.literal(m.name.decoded)
val …Run Code Online (Sandbox Code Playgroud) 我是Java Swing的新手.我正在使用Netbeans的GUI构建器.
我的应用程序中有三个主要面板用于三种不同的视图.可以通过左侧的菜单切换这些视图.
我通过设置一个可见并将另外两个设置为不可见来切换这些视图.它有效,但有一点问题.
为了实现这一点,我必须在GUI构建器中水平放置三个JScrollPanes.每当我切换到视图时,当可见的JScrollPane调整自身以填充整个窗口时,可见组件和不可见组件之间的小间隙仍然存在.它使应用程序看起来非常难看.当我垂直放置时会发生同样的事情.
如何使用GUI构建器解决此问题?显然,我无法对界面设计的代码进行更改.
这是一个非常粗略的问题图,我希望它足够清楚:链接
仅使用一个JScrollPane不是一个选项,因为它们具有不同的布局管理器,并且将具有大量的组件.在用户更改视图时,从一开始就渲染所有内容在性能方面是不可行的.
提前致谢,
埃姆雷
有没有一种方法,以返回List的TypeSymbol使用宏包项下的每个类?
我想要实现的是编写一个宏,它给出了与此列表等效的东西:
scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._
scala> case class MyClass1()
defined class MyClass1
scala> case class MyClass2()
defined class MyClass2
scala> val typeSymbols = List(typeOf[MyClass1].typeSymbol, typeOf[MyClass2].typeSymbol)
typeSymbols: List[reflect.runtime.universe.Symbol] = List(class MyClass1, class MyClass2)
Run Code Online (Sandbox Code Playgroud)
这是我的设置:
我有一个名为的包foo,其中定义了这些包:
trait FooTrait
case class Bar() extends FooTrait
case class Bar() extends FooTrait
Run Code Online (Sandbox Code Playgroud)
这是我的宏,它获取foo下扩展的类的所有类型符号FooTrait:
def allTypeSymbols_impl[T: c.WeakTypeTag](c: Context)(packageName: c.Expr[String]) = {
import c.universe._
// Get package name from the expression tree
val Literal(Constant(name: String)) = packageName.tree
// …Run Code Online (Sandbox Code Playgroud) 我正在尝试实现这里描述的隐式物化器:http://docs.scala-lang.org/overviews/macros/implicits.html
我决定创建一个宏,用于将case类转换为String使用quasiquotes进行原型设计.例如:
case class User(id: String, name: String)
val foo = User("testid", "foo")
Run Code Online (Sandbox Code Playgroud)
foo应该导致转换为文本"testid foo",反之亦然.
这是我创建的简单特征及其伴随对象:
trait TextConvertible[T] {
def convertTo(obj: T): String
def convertFrom(text: String): T
}
object TextConvertible {
import language.experimental.macros
import QuasiTest.materializeTextConvertible_impl
implicit def materializeTextConvertible[T]: TextConvertible[T] = macro materializeTextConvertible_impl[T]
}
Run Code Online (Sandbox Code Playgroud)
这是宏:
object QuasiTest {
import reflect.macros._
def materializeTextConvertible_impl[T: c.WeakTypeTag](c: Context): c.Expr[TextConvertible[T]] = {
import c.universe._
val tpe = weakTypeOf[T]
val fields = tpe.declarations.collect {
case field if field.isMethod && …Run Code Online (Sandbox Code Playgroud) 我如何编写使用变量作为类型?例如:
scala> class A
defined class A
scala> class B extends A
defined class B
scala> def convert[F, T](from: F): T = from.asInstanceOf[T]
convert: [F, T](from: F)T
scala> val b = new B
b: B = B@54038f36
scala> convert[B, A](b)
res18: A = B@54038f36
Run Code Online (Sandbox Code Playgroud)
这很好用.但我有兴趣做:
scala> val aType = classOf[A]
aType: Class[A] = class A
scala> convert[B, aType](b)
<console>:12: error: not found: type aType
convert[B, aType](b)
Run Code Online (Sandbox Code Playgroud)
如果没有初始化对象并obj.type在那里使用,我该怎么做?我怀疑我需要使用一些反射功能(可能TypeTag?),但我无法找到在这里使用的正确的东西.
谢谢!
我有一个非常简单的案例类,叫做FooPosition:
case class FooPosition(x: Int, y: Int)
Run Code Online (Sandbox Code Playgroud)
和一个Foo有一个FooPosition.我感兴趣的是创建一个函数,该函数仅对于(x-1, y)相对于Foo对象的坐标返回-1,并在其他地方返回0.所以我写道:
class Foo(position: FooPosition) {
def bar = (p: FooPosition) => p match {
case FooPosition(position.x - 1, position.y) => -1
case FooPosition(_, _) => 0
}
}
Run Code Online (Sandbox Code Playgroud)
这会导致出现"未找到:值 - "的错误.有趣的是,
val myFoo = FooPosition(1, 0)
val newFoo = FooPosition(myFoo.x - 1, myFoo.y)
Run Code Online (Sandbox Code Playgroud)
工作得很好.我在这里显然缺少关于模式匹配的东西(因为我是初学者).但是这个问题的优雅解决方案是什么?我已经解决了这个问题
class Foo(position: FooPosition) {
private val left = FooPosition(position.x - 1, position.y)
def bar = (p: FooPosition) => p match …Run Code Online (Sandbox Code Playgroud)