字符串的类型以不同方式进行转义/编码

时间:2015-01-20 08:46:16

标签: string scala encoding types escaping

最近我正在处理转义/编码问题。我有一堆API以不同方式接收和返回Strings编码/转义。为了清理混乱,我想引入新类型XmlEscapedStringHtmlEscapedStringUrlEncodedString等,并使用它们代替Strings

问题是编译器无法检查编码/转义,我将遇到运行时错误。

我还可以根据需要提供转义/编码输入的“转换”功能。它有意义吗?

1 个答案:

答案 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传递,编译器将强制我们永远不会将非转义字符串传递给期望它的方法。