xcode Swift3.0 无法将“ClosedRange<Index>”类型的值转换为“Range<Index>”类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38991477/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Swift3.0 Cannot convert value of type 'ClosedRange<Index>' to type 'Range<Index>'
提问by Anna23
I'm trying to migrate the Swift 2.3 to 3.0 and post-conversion facing this issue. Any suggestion what I'm doing wrong.
我正在尝试将 Swift 2.3 迁移到 3.0 并在转换后面临此问题。任何建议我做错了什么。
Swift 3.0:
斯威夫特 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>')
错误:
让 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>')
Original code: Swift 2.3
原始代码:Swift 2.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
}
回答by dfri
You can use ..<
instead of ...
for range
to be of type Range<Index>
instead of ClosedRange<Index>
, in which case the call to stringByReplacingCharactersInRange(...)
wont yield an error (notice the offsetBy
increase by 1
).
您可以使用..<
代替...
forrange
来Range<Index>
代替类型ClosedRange<Index>
,在这种情况下,调用stringByReplacingCharactersInRange(...)
不会产生错误(注意offsetBy
增加了1
)。
let range = key.startIndex..<key.index(key.startIndex, offsetBy: 1)
// range is now type Range<Index>
Now, I might be wrong, but it seems as if you simply want the selectorString
to be the version of key
with the first character uppercased. An alternative method to your range solution you can e.g. use a String
extension solution as follows:
现在,我可能是错的,但似乎您只是希望 theselectorString
成为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
回答by Dasoga
Swift 3+
斯威夫特 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)
}