【问题标题】:Swift from generic type to CustomStringConvertibleSwift 从泛型类型到 CustomStringConvertible
【发布时间】:2015-10-01 23:11:52
【问题描述】:

我整理了以下课程(在Swift variable comparison where type is not known 中的其他人的帮助下)。

我想要实现的是向 SearchOption 传递一个闭包,当调用 getSelectedItemAsString 时,它将运行以 searchOption 作为参数传递的闭包并返回结果。

但是因为selectedOption 是一个泛型类型,它在getSelectedItemAsString() 中抱怨Cannot convert value of type '[T]' to expected argument type '[CustomStringConvertible]'

public func getSelectedItemAsString() -> String {
    if self.searchOptionToString != nil && self.selectedOption != nil {
        return self.searchOptionToString!(selectedOption!)
    }
    return ""
}

我不确定在这里做什么。对于每个 SearchOption,将 searchOption 转换为字符串的实现会有所不同,这就是我需要闭包的原因。

全班

public typealias searchOptionToCloudSearchQuery = ([CustomStringConvertible]) -> String

public class SearchOption<T: Equatable> {

    private var title: String
    private var allowAny: Bool
    private var allowMultiple: Bool
    private var dependencies: [SearchOption]?

    private var selectedOption: [T]?

    private var searchOptionToString: searchOptionToCloudSearchQuery?

    init(title: String, allowAny: Bool, allowMultiple: Bool, dependencies: [SearchOption]?) {
        self.title = title
        self.allowAny = allowAny
        self.allowMultiple = allowMultiple
        self.dependencies = dependencies
    }

    public func setSelectedItem(selectedOption: T) -> Void {
        if self.selectedOption == nil || !self.allowMultiple{
            self.selectedOption = [T]()
        }
        self.selectedOption?.append(selectedOption)
    }

    public func getSelectedItem() -> [T]? {
        return self.selectedOption
    }

    public func setSearchOptionToCloudSearchQueryClosure(closure: searchOptionToCloudSearchQuery) -> Void {
        self.searchOptionToString = closure
    }

    public func getSelectedItemAsString() -> String {
        if self.searchOptionToString != nil && self.selectedOption != nil {
            return self.searchOptionToString!(selectedOption!)
        }
        return ""
    }

}

实施

var make: SearchOption = SearchOption<String>(title: "Make", allowAny: true, allowMultiple: true, dependencies: nil)

make.setSelectedItem("Vauxhall")

var closure: searchOptionToCloudSearchQuery = {(selectedOptions) in

    var stringBuilder = ""
    for item in selectedOptions {
        if item is String {
            stringBuilder += item as! String
        }
    }
    return stringBuilder

}

make.setSearchOptionToCloudSearchQueryClosure(closure)
make.getSelectedItemAsString()

错误

Playground execution failed: /var/folders/b5/3jvkp2jd5q5fmps2hrw91781cmf7f_/T/./lldb/570/playground442.swift:38:61: error: cannot convert value of type '[T]' to expected argument type '[CustomStringConvertible]'
            return self.searchOptionToString!(selectedOption!)
                                              ~~~~~~~~~~~~~~^

【问题讨论】:

    标签: swift generics closures


    【解决方案1】:

    我已经设法解决了我的问题。

    我不是在实现中使用类型别名,而是在定义闭包的同时定义类型:

    var closure: ([String]) -> String = {(selectedOptions) in
    
        var stringBuilder = ""
        for item in selectedOptions {
            stringBuilder += item
        }
        return stringBuilder
    
    }
    

    然后将 typealias 移动到类本身,参数上带有泛型类型,这样可以确保闭包类型和 searchOption 类型匹配:

    public class SearchOption<T: Equatable> {
    
        public typealias searchOptionToCloudSearchQuery = ([T]) -> String
    
        /.../
    
        public func getSelectedItemAsString() -> String {
            if self.searchOptionToString != nil && self.selectedOption != nil {
                return self.searchOptionToString!(selectedOption!)
            }
            return ""
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-21
      • 1970-01-01
      • 1970-01-01
      • 2018-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-27
      相关资源
      最近更新 更多