Swift 从通用类型到 CustomStringConvertible
Swift from generic type to CustomStringConvertible
我整理了以下 class(在 中其他人的帮助下)。
我想要实现的是将闭包传递给 SearchOption 并且在调用 getSelectedItemAsString
时它将 运行 闭包作为参数传入 searchOption
和 return结果。
但是因为 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 都是不同的,这就是我需要闭包的原因。
完整class
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!)
~~~~~~~~~~~~~~^
我已经解决了我的问题。
我没有在实现中使用类型别名,而是在定义闭包的同时定义了类型:
var closure: ([String]) -> String = {(selectedOptions) in
var stringBuilder = ""
for item in selectedOptions {
stringBuilder += item
}
return stringBuilder
}
然后将 typealias 移动到 class 本身,并在参数上使用通用类型,这确保了闭包类型和 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 ""
}
}
我整理了以下 class(在
我想要实现的是将闭包传递给 SearchOption 并且在调用 getSelectedItemAsString
时它将 运行 闭包作为参数传入 searchOption
和 return结果。
但是因为 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 都是不同的,这就是我需要闭包的原因。
完整class
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!)
~~~~~~~~~~~~~~^
我已经解决了我的问题。
我没有在实现中使用类型别名,而是在定义闭包的同时定义了类型:
var closure: ([String]) -> String = {(selectedOptions) in
var stringBuilder = ""
for item in selectedOptions {
stringBuilder += item
}
return stringBuilder
}
然后将 typealias 移动到 class 本身,并在参数上使用通用类型,这确保了闭包类型和 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 ""
}
}