最近我正在处理转义/编码问题。我有一堆API以不同方式接收和返回Strings
编码/转义。为了清理混乱,我想引入新类型XmlEscapedString
,HtmlEscapedString
,UrlEncodedString
等,并使用它们代替Strings
。
问题是编译器无法检查编码/转义,我将遇到运行时错误。
我还可以根据需要提供转义/编码输入的“转换”功能。它有意义吗?
答案 0 :(得分:1)
编译器可以强制您通过编码/解码函数传递类型;这应该足够了,只要你在边界处得到正确的东西(如果你有一个正确编码的XmlEscapedString
并将其转换为UrlEncodedString
,结果总是会被正确编码,不是吗?)。您可以使用最初检查转义的构造函数或转换方法,但这样做可能会导致性能损失。
(从理论上讲,有可能使用类型级编程来检查字符串在编译时的转义,但这非常困难,而且只有在文字时才能使用,当它听起来问题是{{1从其他API进来。)
我自己的妥协立场可能是使用标记类型(使用Scalaz标记)并且从未标记字符串到标记字符串的转换执行检查,即:
String
然后我们将import scalaz._, Scalaz._
sealed trait XmlEscaped
def xmlEscape(rawString: String): String @@ XmlEscaped = {
//perform escaping, guaranteed to return a correctly-escaped String
Tag[String, XmlEscaped](escapedString)
}
def castToXmlEscaped(escapedStringFromJavaApi: String) = {
require(...) //confirm that string is properly escaped
Tag[String, XmlEscaped](escapedStringFromJavaApi)
}
def someMethodThatRequiresAnEscapedString(string: String @@ XmlEscaped)
用于已经应该进行XML转义的castToXmlEscaped
,所以我们检查一下,但我们只需要检查一次;其余的时间我们将它作为Strings
传递,编译器将强制我们永远不会将非转义字符串传递给期望它的方法。