如何对 String 和 NSAttributedString 使用通用类型?

How do I use a use a generic type for both String and NSAttributedString?

我有一个将 bold 设置为 String 的扩展。

extension NSAttributedString {
    convenience init(format: NSAttributedString, makeBold: [String], regularText: [String]) {
        let mutableString = NSMutableAttributedString(attributedString: format)
        
        makeBold.forEach { string in
            let range = NSString(string: mutableString.string).range(of: "%bold%")
            let attributedString = NSAttributedString(string: string, attributes: [.font: UIFont.openSans(style: .bold, size: 15)])
            mutableString.replaceCharacters(in: range, with: attributedString)
            
        }
        
        regularText.forEach { text in
            let textRange = NSString(string: mutableString.string).range(of: "%regular%")
            mutableString.replaceCharacters(in: textRange, with: text)
        }
        self.init(attributedString: mutableString)
    }
}

它工作正常,但我需要 regularText: [String] 才能接受 [NSAttributedString]。我试着这样做:

convenience init<T>(format: NSAttributedString, makeBold: [String], regularText: [T])

但这给了我一个错误:

mutableString.replaceCharacters(in: textRange, with: text)

带有错误文本

No exact matches in call to instance method 'replaceCharacters(in:with:)'

不太熟悉 generics 我不确定如何进行这项工作。如有任何帮助,我们将不胜感激。

我读到这里

这是使用错误类型的一般错误,所以我想我没有generics正确。

编辑 如果我将 regularText 类型从 String 更改为 NSAttributedString 它可以正常工作,那么为什么两者都不能通用?

更新(见评论):添加另一个便利 init

convenience init(format: NSAttributedString, makeBold: [String], regularText: [NSAttributedString]) {
    self.init(format: format, makeBold: makeBold, regularText: regularText.map{ [=10=].string })
}

或 只需添加另一个方便的 init

convenience init(format: NSAttributedString, makeBold: [String], regularText: [NSAttributedString]) {
    self.init(format: format, makeBold: makeBold, regularText: regularText.asStringArray)
}

还有这样的扩展

extension Array where Element: NSAttributedString {
    var asStringArray: [String] {
        var strings: [String] = []
        
        self.forEach { text in
            strings.append(text.string)
        }
        
        return strings
    }
}