我需要将Integer值转换为String。我用一个Integer值创建了一个变量,然后使用进行了打印print。以下方法之间有什么区别?
var word = "Count is "
var count = 100
print(word+String(describing: count)); // Count is 100
print(word+String(count)); // Count is 100
Run Code Online (Sandbox Code Playgroud)
阅读文档可能会有所帮助!
这是摘录自 String.init(describing:)
使用此初始值设定项将任何类型的实例转换为其首选表示形式为 String 实例。初始
instance值设定项以下列方式之一创建字符串表示,具体取决于其协议一致性:
- 如果实例符合
TextOutputStreamable协议,则通过调用instance.write(to: s)空字符串 s获得结果。- 如果实例符合
CustomStringConvertible协议,则结果为instance.description。- 如果实例符合
CustomDebugStringConvertible协议,则结果为instance.debugDescription。- Swift 标准库会自动提供未指定的结果。
Int符合CustomStringConvertible,因此String(describing: someInt)与 相同someInt.description。
现在让我们看看String(someInt),它调用了这个初始化器:
public init<T>(_ value: T) where T : LosslessStringConvertible
Run Code Online (Sandbox Code Playgroud)
Int也符合LosslessStringConvertible. 事实上,LosslessStringConvertible继承自CustomStringConvertible. LosslessStringConvertible仅指定一个要求 - 一个接受字符串的初始化程序。
的文档是这样init<T>(_:)说的:
根据给定
LosslessStringConvertible实例的描述创建一个实例。
即使description不是等宽字体,我敢肯定(虽然不是100%),这指description的财产CustomStringConvertible。
假设init<T>(_:)确实返回description,则String(describing: someInt)始终返回与 相同的值String(someInt)。
请注意,这并不适用于所有类型。它仅适用于符合LosslessStringConvertible但不符合 的类型TextOutputStreamable。如果您的类型同时符合两者,结果可能会有所不同:
struct A: TextOutputStreamable, LosslessStringConvertible {
init?(_ description: String) { }
init() { }
var description: String {
return "foo"
}
func write<Target>(to target: inout Target) where Target : TextOutputStream {
target.write("bar")
}
}
String(describing: A()) // bar
String(A()) // foo
Run Code Online (Sandbox Code Playgroud)
你的问题其实是不必要的,因为如果所有你想要做的,是打印,你可以直接做到这一点:
print("Count is", count) // Count is 100
Run Code Online (Sandbox Code Playgroud)
那是因为print需要可变参数并插入空格作为默认分隔符。
但是,还是让我们回答这个问题。
这是强制和表征之间的区别。
强制性的。某些类型可以更改为某些其他类型。您可以将Double更改为Int,也可以将Int更改为Double。您可以将Int更改为String,并将String(也许)更改为Int。这是可能的,因为第二种类型有一个参数为第一种类型的初始化程序。您可以在实际程序中执行以下操作:
let sum : Int = x + y
self.myLabel.text = "Your total is \(String(sum))"
Run Code Online (Sandbox Code Playgroud)
表示形式。出于调试目的,所有类型都可以从可表示为字符串的形式中受益。假设您有一个Person类型。您不能将Person更改为String,反之亦然-这没有意义-但是您肯定希望能够将printPerson更改为控制台,以查看是否获得正确的结果。这是可能的,因为Person类型本身提供了可打印的描述。您可以出于调试目的执行以下操作:
let p = Person(first:"Matt", last:"Neuburg")
print("p is \(String(describing:p))")
Run Code Online (Sandbox Code Playgroud)
评论1。在Swift中,这种区别是相当新的。它曾经String(...)是用来表达这两个概念的。但是人们意识到,这是两种截然不同的机制的混淆。因此,如今,写尝试String(p)将失败,而较早时它将成功。字符串没有人初始值设定项,因此String(p)被禁止;您现在必须明确地说出您正在描述,而不是强迫。
评论2。很明显,打印描述很普遍,String(describing:)如果您只想记录对象本身,就不必通过。你可以写print(p),因为这是一个速记的print(String(describing:p))。同样,字符串插值会要求String(describing:)您执行操作,因此您可以编写print("p is \(p)")。而且,正如我一开始所说的,print它采用可变参数,并插入空格作为默认分隔符,因此您可以编写print("p is", p)。
| 归档时间: |
|
| 查看次数: |
5086 次 |
| 最近记录: |