如何在Swift中将字符串用作可打印项
我正在尝试编写一个函数,该函数接受类型为Printable的参数:如何在Swift中将字符串用作可打印项,swift,Swift,我正在尝试编写一个函数,该函数接受类型为Printable的参数: func logMessage(message: Printable) { // ... } 奇怪的是,当传入字符串时,这并不像预期的那样工作 这不会编译: logMessage("some string \(someVariable)") // Neither does this: let aString = "aString" logMessage(aString) 然而,本文件汇编了: logMessage(
func logMessage(message: Printable) {
// ...
}
奇怪的是,当传入字符串时,这并不像预期的那样工作
这不会编译:
logMessage("some string \(someVariable)")
// Neither does this:
let aString = "aString"
logMessage(aString)
然而,本文件汇编了:
logMessage("A string")
// This works too:
let aString: Printable = "a string"
logMessage(aString)
let aString: Printable = "Ceci n'est pas une String"
这很令人困惑。似乎在某些情况下字符串实现了可打印,而在另一些情况下不是
此外,字符串插值似乎总是生成一个不实现可打印的字符串。此操作在运行时崩溃,并出现强制转换错误:
let aString = "a string"
let interpolatedString = "contains \(aString)"
你知道这是怎么回事吗?你是对的,
String
不符合Printable
。其原因如下:
logMessage("A string")
// This works too:
let aString: Printable = "a string"
logMessage(aString)
let aString: Printable = "Ceci n'est pas une String"
您不是在用该文本创建一个字符串
,而是在创建一个NSString
(它是可打印的
)
通常,在Swift中,编写受协议约束的通用函数通常更好。所以不是
func logMessage(message: Printable) {
// ...
}
你最好写下:
func logMessage<T: Printable>(message: T) {
// ...
}
这将适用于字符串
,实际上也适用于任何不可打印的
(尽管您将得到一个涉及损坏的类名的毫无帮助的输出)
或者,您可以使用Streamable
哪些字符串符合:
func logMessage<T: Streamable>(message: T) {
println(message)
}
let s: String = "hello"
logMessage(s)
func日志消息(消息:T){
println(消息)
}
让我们:String=“你好”
日志信息
我想我在twitter上读到过一段时间,Swift团队的一位成员提到,
String
不符合Printable
的原因正是因为他们不希望人们像这样直接使用Printable
,最好总是使用toString
或类似的东西在此注释中,它的行为正确:“没有理由将Printable用作类型或泛型约束。println()和toString()可用于任何类型,应该使用它而不是访问“description”属性。”@NateCook是的,我个人认为可以指定类型需要提供正确格式的描述,而不是作为函数signatureKind的一部分的损坏的类型名,因为该字符串不能实现可打印。我想第三种解决方案是在字符串扩展中实现可打印。@MihaiDamian我同意这是意外的,但本质上苹果说的是编写
函数,而不是
,并使用toString()
无论您在何处使用了description
属性。因此我很好奇:如果我甚至没有为参数使用协议,为什么logMessage(message:T)比logMessage(message:Any)更好。它只是为了帮助编译器进行优化,因为类型将在编译时确定吗?