gpt4 book ai didi

Swift - 如何使用类类型作为参数/变量

转载 作者:行者123 更新时间:2023-11-28 05:39:06 26 4
gpt4 key购买 nike

我正在尝试创建一个有点通用的函数来根据属性值对文件 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
}
}

//Generic function to get a files attributes from a URL by requested 
type

func sortFileArrayByType(fileAttributeKeyString : String, fileURLArray : [URL], type: String, isSortOrderDesc : Bool) -> [URL] {
let fileManager = FileManager.default
let attributeToLookFor : FileAttributeKey = FileAttributeKey.init(rawValue: fileAttributeKeyString)
var tupleArrayWithURLandAttribute : [(url: URL, attribute: *Any*)]? = nil

for url in fileURLArray {
do {
let attributes = try fileManager.attributesOfItem(atPath: url.path)
for (key, value) in attributes {
if key.rawValue == fileAttributeKeyString {
tupleArrayWithURLandAttribute?.append((url: url, attribute: value))
}

}
let sortedTupleArrayWithURLandAttribute = tupleArrayWithURLandAttribute?.sorted(by: { $0.attribute < $1.attribute)})
// Need to Sort dictionary into array
return sortedTupleArrayWithURLandAttribute
} catch {
return fileURLArray
}
}
}

最佳答案

先读 Metatype TypeThe Swift Programming Language 中。阅读后继续回答。

从中您了解到可以将函数参数的类型声明为类型的类型(您可以斜视),又名 元类型,因此可以将类型传递给函数.将它与泛型和 Swift 的类型推断相结合,您可以将您的函数声明为:

func sortFileArrayByType<T>(fileAttributeKeyString : String,
attributeType : T.Type,
fileURLArray : [URL]
) -> [(url: URL, attribute: T)]
where T : Comparable

这添加了参数 attributeType,其类型是 T 的元类型,其中 T 将被推断。例如,可以传递元类型 String.self 并且 T 将被推断为 String

where 子句约束T,以便只允许Comparable 类型,这是启用函数进行排序所必需的。文件属性可以是DateStringNSNumber 值;不幸的是,后者不符合 Comparable 所以你需要添加一个扩展来实现它,以下就足够了:

extension NSNumber : Comparable
{
public static func <(a : NSNumber, b : NSNumber) -> Bool { return a.compare(b) == .orderedAscending }
public static func ==(a : NSNumber, b : NSNumber) -> Bool { return a.compare(b) == .orderedSame }
}

在函数体内,您需要声明元组数组具有 T 类型的属性:

var tupleArrayWithURLandAttribute : [(url: URL, attribute: T)] = []

当您添加条目时,您需要将 attributesOfItem 返回的值转换为 T:

tupleArrayWithURLandAttribute.append((url: url, attribute: value as! T))

注意这里使用了 as!,你必须在函数调用中正确匹配属性名称和它的值的类型,否则你将得到运行时中止。如果需要,将其作为软错误处理,留作练习。

您发布的代码中有许多拼写错误等,这些问题留给您修复,完成后您的功能应该可以正常工作。调用可能如下所示:

let ans = sortFileArrayByType2(fileAttributeKeyString: "NSFileCreationDate",
attributeType: Date.self,
fileURLArray: urlArray)

在这种情况下,ans 的类型将是 [(url: URL, attribute: Date)]

HTH

关于Swift - 如何使用类类型作为参数/变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57582200/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com