scala – 在宏中使用私有构造函数
我想在宏中使用一个私有的构造函数。此示例为正整数,但基本模式不仅可用于其他数字类型,如偶数,还可用于字符串派生类型,如电子邮件地址或目录名称。通过使构造函数为私有,用户被拒绝机会进??行非法类型。我有以下代码:
object PosInt { import language.experimental.macros import reflect.runtime.universe._ import reflect.macros.Context def op(inp: Int): Option[PosInt] = if (inp > 0) Some(new PosInt(inp)) else None def apply(param: Int): PosInt = macro apply_impl def apply_impl(c: Context)(param: c.Expr[Int]): c.Expr[PosInt] = { import c.universe._ param match { case Expr(Literal(i)) if (i.value.asInstanceOf[Int] > 0) => case Expr(Literal(i)) if (i.value.asInstanceOf[Int] == 0) => c.abort(c.enclosingPosition,"0 is not a positive integer") case Expr(Literal(i)) => c.abort(c.enclosingPosition,"is not a positive integer") case _ => c.abort(c.enclosingPosition,"Not a Literal") } reify{new PosInt(param.splice)} } } class PosInt (val value: Int) extends AnyVal 但是,如果我使PosInt构造函数是私有的,虽然Macro按预期编译,但如果尝试使用宏,则会收到错误。我无法手动构建表达式树,但我不知道这是否会有帮助。有没有办法我可以做到这一点? 即使PosInt不是值类,你仍然无法使用私有构造函数。我会接受一个不使用价值类的答案。值类的缺点是它们得到类型擦除。加上我对2d坐标的子集感兴趣的课程无法实现为价值类。我对实体整数并不感兴趣,我只是用它们作为一个简单的测试台。我正在使用Scala 2.11M5。 Scala 2.11将添加quasiquote功能。我还没有弄清楚如何使用quasiquotes,因为现在所有的材料似乎都熟悉了我没有的宏观乐园。 解决方法
不幸的是,为了实现这些目标,宏不能这样工作。他们只是在编译时操纵AST。无论最终的结果如何,它总是可以在Scala中写的(没有宏)。
因此,为了限制PosInt的可能值,您需要在公共构造函数或伴随对象的工厂方法中进行运行时检查。 如果运行时异常不适合你,那么一种可能的方法是: >使构造函数在类上私有。 在这种情况下,在Option上调用.get是可以接受的,因为你确定它永远不会是None。 缺点是你必须重复两次检查:一次在编译时,一次在运行时。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |