Swift 3:如何检查泛型数组的类型
我声明一个泛型数组Swift 3:如何检查泛型数组的类型,swift,Swift,我声明一个泛型数组 fileprivate var array: [T?] 我有一个方法average(),如果'T'是Int或Float,它将计算average;否则返回0 public func average() -> Float { var mean = 0 if T is Int or Float { for index in (0..<array.count-1){ mean = mean+array[inde
fileprivate var array: [T?]
我有一个方法average(),如果'T'是Int或Float,它将计算average;否则返回0
public func average() -> Float {
var mean = 0
if T is Int or Float {
for index in (0..<array.count-1){
mean = mean+array[index]
}
mean = mean/array.count
}
return mean;
}
public func average()->Float{
var平均值=0
如果T是Int或Float{
对于(0..中的索引,您需要迭代数组,并使用“if let”打开数组中值的类型。如果它们是int,则以一种方式处理它们,如果它们是float,则以另一种方式处理它们
//在遍历数组时,检查元素是否为浮点或整数
if let stringArray = T as? Int {
// obj is a string array. Do something with stringArray
}
else {
// obj is not a string array
}
您需要迭代数组,并使用“if let”打开数组中值的类型。如果它们是int,则以一种方式处理它们,如果它们是float,则以另一种方式处理它们
//在遍历数组时,检查元素是否为浮点或整数
if let stringArray = T as? Int {
// obj is a string array. Do something with stringArray
}
else {
// obj is not a string array
}
您可以通过以下方式使用Swift 3中引入的类型
方法:
let type = type(of: array)
print("type: \(type)") // if T is String, you will see Array<Optional<String>> here
let type=type(of:array)
print(“type:\(type)”//如果T是字符串,您将在这里看到数组
您可以通过以下方式使用Swift 3中引入的类型
方法:
let type = type(of: array)
print("type: \(type)") // if T is String, you will see Array<Optional<String>> here
let type=type(of:array)
print(“type:\(type)”//如果T是字符串,您将在这里看到数组
下面是一个高级描述:
... inside a loop which allows indexing
if let ex = array[index] as? Int {
your code
continue // go around the loop again, you're all done here
}
if let ex = array[index] as? Float {
// other code
continue // go around the loop again, you're all done here
}
// if you got here it isn't either of them
// code to handle that
... end of inside the loop
如果这还不够清楚,我可以进一步解释。这里有一个高层描述:
... inside a loop which allows indexing
if let ex = array[index] as? Int {
your code
continue // go around the loop again, you're all done here
}
if let ex = array[index] as? Float {
// other code
continue // go around the loop again, you're all done here
}
// if you got here it isn't either of them
// code to handle that
... end of inside the loop
如果这还不够清楚,我可以进一步解释。这可能是最简单的方法:
var average: Float {
let total = array.reduce(0.0) { (runningTotal, item) -> Float in
if let itemAsFloat = item as? Float {
return runningTotal + itemAsFloat
}
else if let itemAsInt = item as? Int {
return runningTotal + Float(itemAsInt)
}
else {
return runningTotal
}
}
return total / Float(array.count)
}
显然,如果您想要它,它可以是一个函数,并且取决于您想要如何使用它,您可能需要调整它
*请注意,可以将Int
和Float
放在T
数组中。例如,如果T
是Any
,这可能是最简单的方法:
var average: Float {
let total = array.reduce(0.0) { (runningTotal, item) -> Float in
if let itemAsFloat = item as? Float {
return runningTotal + itemAsFloat
}
else if let itemAsInt = item as? Int {
return runningTotal + Float(itemAsInt)
}
else {
return runningTotal
}
}
return total / Float(array.count)
}
显然,如果您想要它,它可以是一个函数,并且取决于您想要如何使用它,您可能需要调整它
*请注意,在T
数组中可以同时包含Int
和Float
。例如,如果T
是Any
,这是一个协议工具。解决问题的有用协议是FloatingPoint
来处理浮点类型(如Float
)和Integer
来处理有符号整数类型(如Int
)。这些类型的实现略有不同,因此最好分别编写每个类型。这样做将确保此方法仅适用于适当类型的T
(而不是所有可能的类型,在这些情况下只返回0)
编辑:在下面的Caleb的评论中再详细介绍一下,你可能会想把整数转换成浮点来生成它们的平均值是可以的。但是在没有仔细考虑你的范围的情况下,这通常是不安全的。例如,考虑平均值<代码> [In .min,In .Max ] < /代码>。[-9223372036854775808, 9223372036854775807]
。平均值应该是-0.5,这是我上面的示例返回的结果。但是,如果你将所有内容都转换为浮点数进行求和,你会得到0,因为Float
无法精确地表达Int.max
。我曾在实时代码中看到,当人们不记得非常大的浮点数时,x==x+1
Float(Int.max) == Float(Int.max - 1) // true
这是一个协议工具。解决问题的有用协议是处理浮点类型(如
Float
)的FloatingPoint
)和处理有符号整数类型(如Int
)的Integer
)。这些实现略有不同,因此最好分别编写每个实现。这样做将确保此方法仅适用于适当类型的T
(而不是所有可能的类型,在这些情况下仅返回0)
编辑:在下面的Caleb的评论中再详细介绍一下,你可能会想把整数转换成浮点来生成它们的平均值是可以的。但是在没有仔细考虑你的范围的情况下,这通常是不安全的。例如,考虑平均值<代码> [In .min,In .Max ] < /代码>。[-9223372036854775808, 9223372036854775807]。平均值应该是-0.5,这是我上面的示例返回的结果。但是,如果你将所有内容都转换为浮点数进行求和,你会得到0,因为
Float
无法精确地表达Int.max
。我曾在实时代码中看到,当人们不记得非常大的浮点数时,x==x+1
Float(Int.max) == Float(Int.max - 1) // true
为什么不把这个函数放在一个将T约束为Int或Float的扩展中呢?为什么不把这个函数放在一个将T约束为Int或Float的扩展中呢?这似乎打破了DRY原则,不是吗?DRY不是一条不变的定律;它是判断解决方案是否正确的经验法则。附加
average()
无法求和的类型不正确(三个字符串的平均值不是0;它不存在)。可以在Swift中创建稍微干燥的版本,但它需要大量的代码,因为没有统一的类型来处理浮点数和整数。Swift具有显著性(在某些情况下是有意的)在“类似数字的东西”上编写可重用代码的障碍。它确实希望您思考数字类型的不同之处。总有一天,我相信这会有所改进,从而有可能编写一个正确的sum()
来处理“同一类型的数字”如果Int
是可移动的,这在今天是可能的,我不明白为什么它不是,但是今天,Swift经常要求你复制算术代码来正确处理类型差异。@calebkleveter谢谢你的解释。帮助我更好地理解这一点。P.S.爱你。这似乎打破了干式原理,不是吗?干式并不是一条不变的定律;它是一条规则