无法强制将“字符”类型的值转换为“字符串”类型
Posted
技术标签:
【中文标题】无法强制将“字符”类型的值转换为“字符串”类型【英文标题】:Cannot convert value of type 'Character' to type 'String' in coercion 【发布时间】:2017-08-07 12:37:39 【问题描述】:在 Swift 中,我希望以下代码是完全有效的:
let snailCharacter: Character = "????"
let snailString = snailCharacter as String
但显然,它会产生错误:
解决方案是像这样使用String
初始化器:
let snailString = String(snailCharacter)
我认为Character
是String
的一个子集,这让我很惊讶。为什么禁止将Character
转换为String
?
我在 Xcode 9 beta 4 中使用 Swift 4。
【问题讨论】:
String
是 Character
s 的集合。你不能投射,因为那是不同的类型。
这只是一个设计决定,所以只有设计 Swift Character
的人才能解释原因。在 Swift 标准库中,Character
被设计为与 String
完全不同的东西,String
具有用于保存单个 BMP 字符的有效内部表示。因此,Character
和String
之间的关系与as
-casting 提供的任何情况都不匹配: -- 向上转换、桥接、注释文字类型、消除重载函数的歧义。 Int8
可以被认为是Int16
的子集,但不能使用as
-casting 将Int8
转换为Int16
。
来到这里解决错误,我认为问题提供了解决方案,答案只是一个奖励:) +1 两者!
【参考方案1】:
查看documentation,您可以看到,Character
只是Swift
中String
的几种表示之一(重点由我添加到相关部分)
字符串是一系列字符,例如“hello, world”或 “信天翁”。 Swift 字符串由 String 类型表示。这 可以通过各种方式访问字符串的内容,包括 字符值的集合。
在Swift
中,String
不仅仅是Character
s 的数组,这与其他一些语言不同。在Swift
中,Character
只是以某种方式表示String
实例的一种方式。 String
s可以用View
s来表示,如CharacterView
、utf8View
等。
Swift
的String
类型架构背后的关键原则之一是 Unicode 正确性,这也是String
s 不仅仅是Character
s 数组的原因之一。
有关Swift4
中String
更改的更多信息,请参阅String Manifesto。
更具体地说明为什么投射不起作用。铸件有型铸和桥铸两种。类型转换只能在涉及继承的类之间进行。您可以将子类向上转换为其超类,这总是成功的,或者您可以尝试将超类向下转换为子类,这仅在子类实例首先向上转换为其超类时才有效。
从上面的解释中应该很清楚为什么类型转换在Character
和String
之间不起作用,因为这两种类型都不能相互继承。
对于桥接转换,这是 Apple 引入的一种方法,用于在某些 Swift
和 Foundation
类型之间实现互操作性,例如 String
和 NSString
,但由于 String
和 Character
都是 Swift
类型,桥接铸造也与此问题无关。
【讨论】:
能解释为什么不能投吗? @RoboRobok 为了清楚起见,我添加了更多要点,现在检查我的答案并告诉我是否足够清楚。【参考方案2】:首先你需要一个文本表示。您可以像这样仅将Character
的描述转换为String
let snailCharacter: Character = "?"
let snailString = snailCharacter.description as String
【讨论】:
对不起,这是错误的。description
属性用于表示用于调试的变量,在这种情况下使用它只是因为它是 String
并不是一个好主意。另外,这已经是String
,所以你的as String
是多余的。
问题是关于禁止这种铸造背后的推理,而不是关于转换本身的方式。以上是关于无法强制将“字符”类型的值转换为“字符串”类型的主要内容,如果未能解决你的问题,请参考以下文章