Swift3.0 无法将类型 'ClosedRange<Index>' 的值转换为类型 'Range<Index>'
Swift3.0 Cannot convert value of type 'ClosedRange<Index>' to type 'Range<Index>'
我正在尝试将 Swift 2.3 迁移到 3.0,并且 post 转换面临这个问题。任何建议我做错了什么。
Swift 3.0:
override func setValue(_ value: AnyObject?, forKey key: String) {
let uppercasedFirstCharacter = String(key.characters.first!).uppercased()
let range = key.startIndex...key.index(key.startIndex, offsetBy: 0)
let selectorString = key.replacingCharacters(in: range, with: uppercasedFirstCharacter)
let selector = NSSelectorFromString("set\(selectorString):")
let responds = self.responds(to: selector)
if !responds {
return
}
Error:
let selectorString = key.replacingCharacters(in: range, with: uppercasedFirstCharacter)
Cannot convert value of type 'ClosedRange<Index>' (aka 'ClosedRange<String.CharacterView.Index>') to expected argument type 'Range<Index>' (aka 'Range<String.CharacterView.Index>')
原代码:Swift2.3
override func setValue(value: AnyObject?, forKey key: String) {
let uppercasedFirstCharacter = String(key.characters.first!).uppercaseString
let range = key.startIndex...key.startIndex.advancedBy(0)
let selectorString = key.stringByReplacingCharactersInRange(range, withString: uppercasedFirstCharacter)
let selector = NSSelectorFromString("set\(selectorString):")
let responds = self.respondsToSelector(selector)
if !responds {
return
}
您可以使用 ..<
而不是 ...
,因为 range
的类型是 Range<Index>
而不是 ClosedRange<Index>
,在这种情况下调用 stringByReplacingCharactersInRange(...)
不会产生错误(注意 offsetBy
增加 1
)。
let range = key.startIndex..<key.index(key.startIndex, offsetBy: 1)
// range is now type Range<Index>
现在,我可能是错的,但似乎您只是希望 selectorString
成为第一个字符大写的 key
的版本。您可以使用范围解决方案的替代方法,例如使用 String
扩展解决方案如下:
extension String {
var firstCharacterUppercased: String {
guard case let c = self.characters,
let c1 = c.first else { return self }
return String(c1).uppercased() + String(c.dropFirst())
}
}
/* example usage */
let key = "fooBar"
let selectorString = key.firstCharacterUppercased
print(selectorString) // FooBar
Swift 3+
override func setValue(_ value: Any?, forKey key: String) {
let upperCaseFirstCharacter = String(key.characters.first!).uppercased()
let range = key.startIndex..<key.index(key.startIndex, offsetBy: 1)
let selectorString = key.replacingCharacters(in: range, with: upperCaseFirstCharacter)
let selector = NSSelectorFromString("set\(selectorString):")
let responds = self.responds(to: selector)
if !responds{
return
}
super.setValue(value, forKey: key)
}
init(dictionary: [String: Any]){
super.init()
setValuesForKeys(dictionary)
}
我正在尝试将 Swift 2.3 迁移到 3.0,并且 post 转换面临这个问题。任何建议我做错了什么。
Swift 3.0:
override func setValue(_ value: AnyObject?, forKey key: String) {
let uppercasedFirstCharacter = String(key.characters.first!).uppercased()
let range = key.startIndex...key.index(key.startIndex, offsetBy: 0)
let selectorString = key.replacingCharacters(in: range, with: uppercasedFirstCharacter)
let selector = NSSelectorFromString("set\(selectorString):")
let responds = self.responds(to: selector)
if !responds {
return
}
Error:
let selectorString = key.replacingCharacters(in: range, with: uppercasedFirstCharacter)
Cannot convert value of type 'ClosedRange<Index>' (aka 'ClosedRange<String.CharacterView.Index>') to expected argument type 'Range<Index>' (aka 'Range<String.CharacterView.Index>')
原代码:Swift2.3
override func setValue(value: AnyObject?, forKey key: String) {
let uppercasedFirstCharacter = String(key.characters.first!).uppercaseString
let range = key.startIndex...key.startIndex.advancedBy(0)
let selectorString = key.stringByReplacingCharactersInRange(range, withString: uppercasedFirstCharacter)
let selector = NSSelectorFromString("set\(selectorString):")
let responds = self.respondsToSelector(selector)
if !responds {
return
}
您可以使用 ..<
而不是 ...
,因为 range
的类型是 Range<Index>
而不是 ClosedRange<Index>
,在这种情况下调用 stringByReplacingCharactersInRange(...)
不会产生错误(注意 offsetBy
增加 1
)。
let range = key.startIndex..<key.index(key.startIndex, offsetBy: 1)
// range is now type Range<Index>
现在,我可能是错的,但似乎您只是希望 selectorString
成为第一个字符大写的 key
的版本。您可以使用范围解决方案的替代方法,例如使用 String
扩展解决方案如下:
extension String {
var firstCharacterUppercased: String {
guard case let c = self.characters,
let c1 = c.first else { return self }
return String(c1).uppercased() + String(c.dropFirst())
}
}
/* example usage */
let key = "fooBar"
let selectorString = key.firstCharacterUppercased
print(selectorString) // FooBar
Swift 3+
override func setValue(_ value: Any?, forKey key: String) {
let upperCaseFirstCharacter = String(key.characters.first!).uppercased()
let range = key.startIndex..<key.index(key.startIndex, offsetBy: 1)
let selectorString = key.replacingCharacters(in: range, with: upperCaseFirstCharacter)
let selector = NSSelectorFromString("set\(selectorString):")
let responds = self.responds(to: selector)
if !responds{
return
}
super.setValue(value, forKey: key)
}
init(dictionary: [String: Any]){
super.init()
setValuesForKeys(dictionary)
}