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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 09:09:01  来源:igfitidea点击:

Swift3.0 Cannot convert value of type 'ClosedRange<Index>' to type 'Range<Index>'

iphonexcodeswift2swift3xcode8

提问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 rangeto be of type Range<Index>instead of ClosedRange<Index>, in which case the call to stringByReplacingCharactersInRange(...)wont yield an error (notice the offsetByincrease by 1).

您可以使用..<代替...forrangeRange<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 selectorStringto be the version of keywith the first character uppercased. An alternative method to your range solution you can e.g. use a Stringextension 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)
    }