Swift-如何将类类型用作参数/变量
我试图创建一个有点通用的函数,根据属性值对文件URL进行排序 我的目标是: 1) 将URL和一些参数(包括类型)传递给函数。 然后将循环文件的属性 2) 将匹配的文件属性和URL添加到元组数组中 3) 根据找到的属性的值对元组进行排序 4) 返回已排序的数组并按排序顺序显示项目 我认为我需要将属性的类型传递到排序函数中,以便能够在元组中设置它,因为我无法使用“Any”进行排序,但我不确定如何进行排序 我可以将任何内容传递到排序函数中,并在排序函数中构造或解构所需的值,因为这将根据用户选择的操作进行预定义Swift-如何将类类型用作参数/变量,swift,macos,cocoa,Swift,Macos,Cocoa,我试图创建一个有点通用的函数,根据属性值对文件URL进行排序 我的目标是: 1) 将URL和一些参数(包括类型)传递给函数。 然后将循环文件的属性 2) 将匹配的文件属性和URL添加到元组数组中 3) 根据找到的属性的值对元组进行排序 4) 返回已排序的数组并按排序顺序显示项目 我认为我需要将属性的类型传递到排序函数中,以便能够在元组中设置它,因为我无法使用“Any”进行排序,但我不确定如何进行排序 我可以将任何内容传递到排序函数中,并在排序函数中构造或解构所需的值,因为这将根据用户选择的操作进
//Initial implementation to be later tied to IBActions and simplified
func sortFiles(sortByKeyString : String, fileURLArray : [URL]) -> [URL]
{
switch sortByKeyString {
case "date-created-DESC":
let fileAttributeKeyString : String = "creationDate"
let isSortOrderDesc = true
let objectTypeString : String = NSDate.className()
let sortedFileURLArray = sortFileArrayByType(fileAttributeKeyString: fileAttributeKeyString, fileURLArray: fileURLArray, type: objectTypeString, isSortOrderDesc : isSortOrderDesc)
return sortedFileURLArray
default:
return fileURLArray
}
}
//通过请求从URL获取文件属性的通用函数
类型
func sortFileArrayByType(fileAttributeKeyString:String,fileURLArray:[URL],type:String,isSortOrderDesc:Bool)->[URL]{
让fileManager=fileManager.default
让attributeToLookFor:FileAttributeKey=FileAttributeKey.init(原始值:fileAttributeKeyString)
var tuplearyWithUrlAndAttribute:[(url:url,属性:*任意*)]?=nil
用于fileURLArray中的url{
做{
让attributes=try fileManager.attributesOfItem(atPath:url.path)
用于属性中的(键、值){
如果key.rawValue==fileAttributeKeyString{
TuplearyWithUrlAndAttribute?.append((url:url,属性:值))
}
}
让sortedTupleArrayWithURLandAttribute=tupleArrayWithURLandAttribute?排序(按:{$0.attribute<$1.attribute)})
//需要将字典排序为数组
返回已排序的数组,其中包含Url和Attribute
}抓住{
返回fileURLArray
}
}
}
所以我想我知道你的意思,这就是我想到的:
func checkType<T>(_ type: T.Type) {
if type.self == String.self {
print("It's a string!")
} else if type.self == Int.self {
print("It's an int!")
} else {
print("It's something else...")
}
}
希望这有帮助 首先用Swift编程语言阅读。阅读后继续回答
从中您了解到,您可以将函数参数的类型声明为类型类型(您可以斜视),也称为元类型,因此可以将类型传递给函数。将其与泛型和Swift的类型推断相结合,您可以将函数声明为:
func sortFileArrayByType<T>(fileAttributeKeyString : String,
attributeType : T.Type,
fileURLArray : [URL]
) -> [(url: URL, attribute: T)]
where T : Comparable
在函数体中,您需要声明元组数组具有T
类型的属性:
var tupleArrayWithURLandAttribute : [(url: URL, attribute: T)] = []
tupleArrayWithURLandAttribute.append((url: url, attribute: value as! T))
当您添加条目时,需要将attributesOfItem
返回的值转换为T
:
var tupleArrayWithURLandAttribute : [(url: URL, attribute: T)] = []
tupleArrayWithURLandAttribute.append((url: url, attribute: value as! T))
注意as的用法
在这里,您必须在函数调用中正确匹配属性名称及其值的类型,否则将得到运行时中止。如果需要,将其作为软错误进行处理将作为一项练习
在你发布的代码中有许多拼写错误等,它们留给你去修复,你的功能应该可以正常工作。一个电话可能看起来像:
let ans = sortFileArrayByType2(fileAttributeKeyString: "NSFileCreationDate",
attributeType: Date.self,
fileURLArray: urlArray)
在这种情况下,ans
的类型将是[(url:url,属性:Date)]
HTH您在这里寻找的是一种通过URLResourceKey(特别是通过与该键相关的URLResourceValues属性)对URL序列进行排序的方法。不幸的是,UrlResourceValue没有以有用的方式映射到URLResourceKey。但我们可以通过扩展来解决这个问题:
extension URLResourceValues {
static func key<T>(for keyPath: KeyPath<Self, T>) -> URLResourceKey {
switch keyPath {
case \Self.creationDate: return .creationDateKey
// ... Other keys ...
default: fatalError()
}
}
}
我想你可能错误地使用了一些Swift测试版,你可能希望下载它的版本…感谢这里的详细信息和添加的指导!
extension URLResourceValues {
static func key<T>(for keyPath: KeyPath<Self, T>) -> URLResourceKey {
switch keyPath {
case \Self.creationDate: return .creationDateKey
// ... Other keys ...
default: fatalError()
}
}
}
extension URL {
func resourceValue<T>(for keyPath: KeyPath<URLResourceValues, T?>) throws -> T? {
return try resourceValues(forKeys: Set([URLResourceValues.key(for: keyPath)]))[keyPath: keyPath]
}
}
extension Sequence where Element == URL {
func sorted<T>(by keyPath: KeyPath<URLResourceValues, T?>) throws -> [URL]
where ResourceType: Comparable {
return try self
.sorted { (lhs, rhs) in
guard let lhsValue = try lhs.resourceValue(for: keyPath)
else { return true }
guard let rhsValue = try rhs.resourceValue(for: keyPath)
else { return false }
return lhsValue < rhsValue
}
}
}
let sortedFiles = try files.sorted(by: \.creationDate)