Swift 字符串常量的类型是否与字符串文字不同?
Is a Swift String constant of a different type than a String literal?
在 Swift 2.1 中,下面的代码片段会产生错误。
var str = "Hello, playground!"
// Success Case
if "!" == str.characters.last {
print("Tone it down please")
}
// Fail Case
let bang = "!"
if bang == str.characters.last { // this line won't compile
print("Tone it down please")
}
编译器错误说:
Binary operator '==' cannot be applied to operands of type 'String'
and '_Element?'
那么在这种情况下使用 constant 而不是 literal 的推荐方法是什么? (我正在学习 Swift,所以如果有 Swift-er 方法来处理这种比较检查,请随时提及。)
谢谢!
对于您的 "Fail case",这是因为 str.characters.last
是可选的并且是 Character
,但是 bang
是 String
。
您可以安全地展开并与 if let ... where
进行比较,并使用 String()
将 Character
更改为 String
以进行比较:
if let last = str.characters.last where String(last) == bang {
print("Tone it down please")
}
如错误所述,第一个运算符是 String
,第二个运算符是可选的 Character
。
但是您已经证明您知道如何将字符串转换为 Character?
,所以让我们使用它:
if bang.characters.last == str.characters.last {
print("Tone it down please")
}
你知道 bang.characters.last
只是 return "!"
,但现在它将与 str.characters.last
属于同一类型,因此比较它们将变得微不足道.
感谢您的精彩讨论。这是我自己的答案,通过消除无关的可选值来改进说明,并展示类型推断的 好的和坏的 :
let a:String = "!" // type is String
let b:Character = "!" // type is Character
let c = "!".characters.last! // type is _Element
let bang = "!" // inferred type is String
if "!" == a { print("literal matches string") }
if "!" == b { print("literal matches Character") }
if "!" == c { print("literal matches _Element") }
if a == b { print("a matches b") } // Err: 'String' to 'Character'
if a == c { print("a matches c") } // Err: 'String' to '_Element'
if b == c { print("b matches c") } // OK: 'Character' to '_Element'
结论:如果上下文提示,由单引号字符组成的文字可以被识别为 String
或 Character
(或等效的 _Element
)。
重要的是:常量的类型在声明时就永久确定了。文字的类型是从其上下文推断的,因此相同的文字在不同的上下文中可能具有不同的类型。
提供给文字的灵活类型推断不适用于常量。
不确定这是否完全相关,但我发现了这个 post,因为我在 characters.first
、characters.last
和 Int
之间转换时遇到问题。
如果这对任何人有帮助:
let element = characters.first! // the ! is important
let myString = String(element)
let myInt = Int(myString) // may be nil if character is not an int
在 Swift 2.1 中,下面的代码片段会产生错误。
var str = "Hello, playground!"
// Success Case
if "!" == str.characters.last {
print("Tone it down please")
}
// Fail Case
let bang = "!"
if bang == str.characters.last { // this line won't compile
print("Tone it down please")
}
编译器错误说:
Binary operator '==' cannot be applied to operands of type 'String' and '_Element?'
那么在这种情况下使用 constant 而不是 literal 的推荐方法是什么? (我正在学习 Swift,所以如果有 Swift-er 方法来处理这种比较检查,请随时提及。)
谢谢!
对于您的 "Fail case",这是因为 str.characters.last
是可选的并且是 Character
,但是 bang
是 String
。
您可以安全地展开并与 if let ... where
进行比较,并使用 String()
将 Character
更改为 String
以进行比较:
if let last = str.characters.last where String(last) == bang {
print("Tone it down please")
}
如错误所述,第一个运算符是 String
,第二个运算符是可选的 Character
。
但是您已经证明您知道如何将字符串转换为 Character?
,所以让我们使用它:
if bang.characters.last == str.characters.last {
print("Tone it down please")
}
你知道 bang.characters.last
只是 return "!"
,但现在它将与 str.characters.last
属于同一类型,因此比较它们将变得微不足道.
感谢您的精彩讨论。这是我自己的答案,通过消除无关的可选值来改进说明,并展示类型推断的 好的和坏的 :
let a:String = "!" // type is String
let b:Character = "!" // type is Character
let c = "!".characters.last! // type is _Element
let bang = "!" // inferred type is String
if "!" == a { print("literal matches string") }
if "!" == b { print("literal matches Character") }
if "!" == c { print("literal matches _Element") }
if a == b { print("a matches b") } // Err: 'String' to 'Character'
if a == c { print("a matches c") } // Err: 'String' to '_Element'
if b == c { print("b matches c") } // OK: 'Character' to '_Element'
结论:如果上下文提示,由单引号字符组成的文字可以被识别为 String
或 Character
(或等效的 _Element
)。
重要的是:常量的类型在声明时就永久确定了。文字的类型是从其上下文推断的,因此相同的文字在不同的上下文中可能具有不同的类型。
提供给文字的灵活类型推断不适用于常量。
不确定这是否完全相关,但我发现了这个 post,因为我在 characters.first
、characters.last
和 Int
之间转换时遇到问题。
如果这对任何人有帮助:
let element = characters.first! // the ! is important
let myString = String(element)
let myInt = Int(myString) // may be nil if character is not an int