Swift 条件绑定的初始值设定项必须具有可选类型,而不是Int
获取此错误时会说: 条件绑定的初始值设定项必须具有可选类型,而不是IntSwift 条件绑定的初始值设定项必须具有可选类型,而不是Int,swift,Swift,获取此错误时会说: 条件绑定的初始值设定项必须具有可选类型,而不是Int 我一直在琢磨如何摆脱它。我必须使用可选绑定展开值心率。不要强制展开使用条件绑定展开的内容: if let hrAverage: Int = (oldHR1+oldHR2+oldHR3+oldHR4+heartRate!)/5 { print(hrAverage) } else { let hrAverage = (oldHR1+oldHR2+oldHR3+oldHR4) / 4 print(hr
我一直在琢磨如何摆脱它。我必须使用可选绑定展开值心率。不要强制展开使用条件绑定展开的内容:
if let hrAverage: Int = (oldHR1+oldHR2+oldHR3+oldHR4+heartRate!)/5 {
print(hrAverage)
} else {
let hrAverage = (oldHR1+oldHR2+oldHR3+oldHR4) / 4
print(hrAverage)
}
如果在代码的其余部分需要平均值,这里有一种更简洁的方法:
if let hr = heartRate {
let hrAverage: Int = (oldHR1 + oldHR2 + oldHR3 + oldHR4 + hr) / 5
print(hrAverage)
} else {
let hrAverage = (oldHR1 + oldHR2 + oldHR3 + oldHR4) / 4
print(hrAverage)
}
oldHR1+oldHR2+oldHR3+oldHR4+心率/5不生成使用if-let语句所需的可选项
我建议你做以下几点:
let compactArray = [oldHR1, oldHR2, oldHR3, oldHR4] + [heartRate].compactMap{$0}
let hrAverage: Int = compactArray.reduce(0, +)/compactArray.count
现在有了一个变量,可以在if语句之外使用。如果您不需要,可以使用以下解决方案:
let average = {
if let rate = heartRate {
return (oldHR1 + oldHR2 + oldHR3 + oldHR4 + rate) / 5
} else {
return (oldHR1 + oldHR2 + oldHR3 + oldHR4) / 4
}
}()
编号的变量名(如oldHR1、oldHR2等)很好地表明您应该使用数组。在这种情况下,我建议您将这个运行平均值计算提取到它自己的数据类型中,这使得处理这些数据变得非常方便
if let rate = heartRate {
let average = (oldHR1 + oldHR2 + oldHR3 + oldHR4 + rate) / 5
} else {
let average = (oldHR1 + oldHR2 + oldHR3 + oldHR4) / 4
}
像oldHR1、oldHR2等有编号的变量名是一个很好的指示,表明您应该使用数组。好了,这是一个更好的答案-比我的更好@我仍然认为有更好的方法。我会很快删除无关的注释。是否存在一个同时包含.compactMap和.reduce的函数?你在这方面有点作弊,哈。但是你也可以做+heartRate==nil?[]:[heartRate]而不是+[heartRate]。compactMap。在检查可读性时,这似乎更具可读性是主观的,但我能理解你的观点。compactArray可以是一个var,并有条件地将heartRate附加到它,这也是可读的。编码风格是一天结束时的个人偏好。但性能是一个中立的标准:仅在[heartRate]上应用compactMap就可以删除oldHR1、oldHR2、oldHR3、oldHR4上任何不必要的压缩映射。谢谢你的贡献!为什么要将平均值作为IUO?如果您要返回nil,请将其设置为可选的,否则只需将其设置为常规变量-例如,您可以只返回0。它会使应用程序崩溃,即使变量隐式地表示不会崩溃nil@LinusGeffarth10不是一个普遍适用的默认值。如果我正在制作一个应用程序,当心率下降到某个阈值以下(比如30 bpm)时自动向急救服务部门发出警报,那么假设无心率的平均值为0,就会导致错误警报。optional的用途是允许调用方轻松决定如何处理nil情况,而不是让库作者强制使用0。如果调用方真的希望nil为0,他们可以这样做。平均值??0,简单。明白你的意思,接受。但是,为什么要加倍呢!而不是Double?@LinusGeffarth 2,但是,容易的nil合并的好处是语法成本高。零只可能出现在物体生命的最初一段时间。在平均值变为非零后,它们将永远不会再回到零。如果已知不可能再出现零,那么在整个代码中强制安全展开是没有意义的。例如,OP可能有一个采样UI,向用户指示正在采样心率,而不显示心率,直到可以采集足够的样本。@LinusGeffarth此测量心率后,请等待UI完成,并且有足够的样本可用,运行平均数将为非零,并且在对象的剩余生存期内将继续为非零。在这一点之前,完全可能从未调用过平均值函数。
struct RunningAverage {
let maxSize: Int
var samples: [Double]
init(maxSize: Int, initialSamples samples: [Double] = []) {
self.maxSize = maxSize
self.samples = samples
}
mutating func addSample(_ newValue: Double) {
samples.append(newValue)
if maxSize < samples.count { samples.removeFirst() }
}
/// Will return `nil` when there are no samples.
/// This allows for easy nil coalescence, without introducing the full burden of
/// needing to unwrap in the case when the samples are known to be non-empty.
var average: Double! {
if self.samples.isEmpty { return nil }
return samples.reduce(0, +) / Double(samples.count)
}
}
var runningAverage = RunningAverage(maxSize: 5)
let mockSamples = 1...10
let runningAverages = mockSamples.map { mockSample -> Double in
runningAverage.addSample(Double(mockSample))
return runningAverage.average
}
print(runningAverages) // => [1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]