字符串 escaped/encoded 的类型不同
Types for strings escaped/encoded differently
最近我正在处理 escaping/encoding 问题。我有一堆接收和 return Strings
encoded/escaped 不同的 API。为了收拾残局,我想引入新类型 XmlEscapedString
、HtmlEscapedString
、UrlEncodedString
等,并使用它们代替 Strings
.
问题是编译器无法检查 encoding/escaping,我会遇到运行时错误。
我还可以提供 "conversion" 函数,需要时 escape/encode 输入。有道理吗?
编译器可以强制您通过 encoding/decoding 函数传递类型;这应该足够了,前提是你在边界处做对了(如果你有一个正确编码的 XmlEscapedString
并将其转换为 UrlEncodedString
,结果总是会被正确编码,不是吗?)。您可以使用最初检查转义的构造函数或转换方法,尽管您可能会为此付出性能损失。
(理论上,可以使用类型级编程在编译时检查字符串的转义,但这将非常困难,而且无论如何只能对文字起作用,当听起来问题是 String
来自其他 API)。
我自己的妥协立场可能是使用标记类型(使用 Scalaz 标记)并让从未标记字符串到标记字符串的转换执行检查,即:
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)
然后我们使用 castToXmlEscaped
来代替 Strings
已经被认为是 XML-escaped,所以我们在那里检查,但我们只需要检查一次;其余时间我们将它作为 String @@ XmlEscaped
传递,编译器将强制我们永远不会将非转义字符串传递给需要一个的方法。
最近我正在处理 escaping/encoding 问题。我有一堆接收和 return Strings
encoded/escaped 不同的 API。为了收拾残局,我想引入新类型 XmlEscapedString
、HtmlEscapedString
、UrlEncodedString
等,并使用它们代替 Strings
.
问题是编译器无法检查 encoding/escaping,我会遇到运行时错误。
我还可以提供 "conversion" 函数,需要时 escape/encode 输入。有道理吗?
编译器可以强制您通过 encoding/decoding 函数传递类型;这应该足够了,前提是你在边界处做对了(如果你有一个正确编码的 XmlEscapedString
并将其转换为 UrlEncodedString
,结果总是会被正确编码,不是吗?)。您可以使用最初检查转义的构造函数或转换方法,尽管您可能会为此付出性能损失。
(理论上,可以使用类型级编程在编译时检查字符串的转义,但这将非常困难,而且无论如何只能对文字起作用,当听起来问题是 String
来自其他 API)。
我自己的妥协立场可能是使用标记类型(使用 Scalaz 标记)并让从未标记字符串到标记字符串的转换执行检查,即:
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)
然后我们使用 castToXmlEscaped
来代替 Strings
已经被认为是 XML-escaped,所以我们在那里检查,但我们只需要检查一次;其余时间我们将它作为 String @@ XmlEscaped
传递,编译器将强制我们永远不会将非转义字符串传递给需要一个的方法。