Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 3:如何检查泛型数组的类型_Swift - Fatal编程技术网

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.爱你。这似乎打破了干式原理,不是吗?干式并不是一条不变的定律;它是一条规则