小编Emr*_*mre的帖子

Scala Macros:使用Scala中的类字段制作地图

假设我有很多类似的数据类.这是一个示例类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对象中定义了一个宏实现: …

scala case-class scala-macros

33
推荐指数
2
解决办法
8762
查看次数

Scala 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)

annotations scala scala-macros

11
推荐指数
1
解决办法
931
查看次数

Java Swing和Netbeans GUI Designer:当我将它们设置为不可见时,如何消除组件之间的小间隙?

我是Java Swing的新手.我正在使用Netbeans的GUI构建器.

我的应用程序中有三个主要面板用于三种不同的视图.可以通过左侧的菜单切换这些视图.

我通过设置一个可见并将另外两个设置为不可见来切换这些视图.它有效,但有一点问题.

为了实现这一点,我必须在GUI构建器中水平放置三个JScrollPanes.每当我切换到视图时,当可见的JScrollPane调整自身以填充整个窗口时,可见组件和不可见组件之间的小间隙仍然存在.它使应用程序看起来非常难看.当我垂直放置时会发生同样的事情.

如何使用GUI构建器解决此问题?显然,我无法对界面设计的代码进行更改.

这是一个非常粗略的问题图,我希望它足够清楚:链接

仅使用一个JScrollPane不是一个选项,因为它们具有不同的布局管理器,并且将具有大量的组件.在用户更改视图时,从一开始就渲染所有内容在性能方面是不可行的.

提前致谢,

埃姆雷

swing

8
推荐指数
2
解决办法
2万
查看次数

Scala宏:获取要在运行时使用的TypeSymbols列表

有没有一种方法,以返回ListTypeSymbol使用宏包项下的每个类?

我想要实现的是编写一个宏,它给出了与此列表等效的东西:

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)

macros scala scala-macros

7
推荐指数
1
解决办法
1696
查看次数

Scala Macros:使用quasiquotes访问成员

我正在尝试实现这里描述的隐式物化器: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)

macros scala scala-macros

6
推荐指数
1
解决办法
3018
查看次数

Scala:包含类型的变量

我如何编写使用变量作为类型?例如:

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?),但我无法找到在这里使用的正确的东西.

谢谢!

reflection scala

2
推荐指数
1
解决办法
100
查看次数

Scala模式匹配 - 从另一个创建新案例对象时出错

我有一个非常简单的案例类,叫做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)

scala pattern-matching case-class

1
推荐指数
1
解决办法
192
查看次数