微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

类型“MatchedValue”不符合协议“Decodable”

如何解决类型“MatchedValue”不符合协议“Decodable”

我有一个必须符合 Codable 协议的结构。 但是,我收到错误

类型“MatchedValue”不符合协议“Decodable”**

如何使 String.Index 符合 Codable? 谢谢

struct MatchedValue: Codable {
    let value: String
    let range: Range<String.Index>
  }

解决方法

尝试使用 Int 而不是 String.Index。

首先,扩展以获取元素或字符串的位置为 Int 以及使用整数范围的能力:

extension StringProtocol {
    func distance(of element: Element) -> Int? { firstIndex(of: element)?.distance(in: self) }
    
    func distance<S: StringProtocol>(of string: S) -> Int? { range(of: string)?.lowerBound.distance(in: self) }
    
    func substring(with range: Range<Int>) -> String? {
        guard range.lowerBound >= 0 && range.upperBound <= self.count else { return nil }
        
        let lowerBoundStringIndex = self.index(self.startIndex,offsetBy: range.lowerBound)
        let upperBoundStringIndex = self.index(lowerBoundStringIndex,offsetBy: range.upperBound - range.lowerBound)

        return String(self[lowerBoundStringIndex..<upperBoundStringIndex])
    }

    subscript(r: Range<Int>) -> String? { substring(with: r) }
    
    func substring(with range: ClosedRange<Int>) -> String? {
        guard range.lowerBound >= 0 && range.upperBound < self.count else { return nil }
        
        if range.lowerBound == range.upperBound { return "" }
        
        let lowerBoundStringIndex = self.index(self.startIndex,offsetBy: range.upperBound + 1 - range.lowerBound)

        return String(self[lowerBoundStringIndex..<upperBoundStringIndex])
    }
    
    subscript(r: ClosedRange<Int>) -> String? { substring(with: r) }
}

extension Collection {
    func distance(to index: Index) -> Int { distance(from: startIndex,to: index) }
}

extension String.Index {
    func distance<S: StringProtocol>(in string: S) -> Int { string.distance(to: self) }
}

现在您可以使用这个新实现:

let letters = "My string"
letters.count // 9

// get range
let lowerBound: Int? = letters.distance(of: "M")
let upperBound: Int? = letters.distance(of: "g")
let intRange: Range<Int> = lowerBound!..<upperBound!
let intClosedRange: ClosedRange<Int> = lowerBound!...upperBound!

// get substring
letters.substring(with: intRange)           // "My strin"
letters.substring(with: intClosedRange)     // "My string"
// or
letters[intRange]                           // "My strin"
letters[intClosedRange]                     // "My string"

我还包括使用 String.Index 和其他测试的比较。

// For comparison purposes only
let lowerIndex = letters.firstIndex(of: "M")
let upperIndex = letters.firstIndex(of: "g")
let range: Range<String.Index> = lowerIndex!..<upperIndex!
let closedRange: ClosedRange<String.Index> = lowerIndex!...upperIndex!
letters[range]                              // "My strin"
letters[closedRange]                        // "My string"

// Additional implementation tests
letters.substring(with: 3...5)  // "str"
letters.substring(with: 3..<5)  // "st"
letters.substring(with: 0...9)  // nil
letters.substring(with: 0..<9)  // "My string"
letters.substring(with: 2...2)  // ""
letters.substring(with: 2..<2)  // ""

这是我的 gist

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。