繁体   English   中英

如何在编译时使用Scala验证字符串格式

[英]How to validate string format with scala in compile time

我的函数有1个参数,类型是字符串,但长度是4,可以在编译时验证此参数吗?

在haskell和F#中,它们具有类型级别,并且可以在编译时进行验证,例如nonEmptyList。

如何在Scala中制作。 我认为无畏的可以做到这一点,但我不明白

谢谢你的建议

是的,Shapeless可以做到这一点。 也许是这样的:

def f(s: Sized[IndexedSeq[Char], Nat._4]): ...

但是,您将无法直接将字符串传递给它。 您必须执行类似f(Sized('a', 'b', 'c', 'd'))

你不能与香草斯卡拉。

您可以采用的最佳方法是为此创建特殊类型-

  case class SpecialString(string: String) {
    require(string.length == 4)
  }

然后,使您的函数将SpecialString作为参数而不是String

使用宏也是编译时验证的一种选择。 请参阅Arnout Engelen的这篇文章: http : //blog.xebia.com/compile-time-evaluation-scala-macros/

我修改了他的示例,以定义一个字符串验证函数:

object CompileTimeStringCheck {
  import scala.language.experimental.macros

  // This function exposed to consumers has a normal Scala type:
  def stringCheck(s: String): String =
    // but it is implemented as a macro:
    macro CompileTimeStringCheck.stringCheck_impl

  import scala.reflect.macros.blackbox.Context 

  // The macro implementation will receive a 'Context' and
  // the AST's of the parameters passed to it:
  def stringCheck_impl(c: Context)(s: c.Expr[String]): c.Expr[String] = {
    import c.universe._

    // We can pattern-match on the AST:
    s match {
      case Expr(Literal(Constant(nValue: String))) =>
        // We perform the calculation:
        val result = normalStringCheck(nValue)
        // And produce an AST for the result of the computation:
        c.Expr(Literal(Constant(result)))
      case other => 
        // Yes, this will be printed at compile time:
        println("Yow!")
        ??? 
    }
  }

  // The actual implementation is regular old-fashioned scala code:    
  private def normalStringCheck(s: String): String =
    if (s.length == 4) return s
    else throw new Exception("Baaaaaah!")
}

不过,这里有个要注意的地方:需要对其进行编译,然后才能使用它,即将其放入utils jar或其他东西中。 然后,您可以在以后的编译时使用它:

import CompileTimeStringCheck._

object Test extends App {
  println(stringCheck("yes!"))
}  

再次,请参阅Arnout Engelen的文章以了解更多详细信息和原始解决方案( http://blog.xebia.com/compile-time-evaluation-scala-macros/ )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM