我正在阅读博客,并且有一个类似下面的功能。我想知道以这种方式编写它的目的是什么?
public func moveNinjaToBottomRight() {
ninja.center = {
let x = (frame.maxX - ninja.frame.width / 2)
let y = (frame.maxY - ninja.frame.height / 2)
return CGPoint(x: x, y: y)
}()
}
答案 0 :(得分:1)
这只是风格问题。
以这种方式编写函数:
public func moveNinjaToBottomRight() {
ninja.center = {
let x = (frame.maxX - ninja.frame.width / 2)
let y = (frame.maxY - ninja.frame.height / 2)
return CGPoint(x: x, y: y)
}()
}
增加了功能目的的清晰度。一眼就可以看到它只是更新ninja.center
而且您知道闭包内的代码正在计算新的中心。如果计算新中心需要更多的线路,情况尤其如此。
另一种写作方式是:
public func moveNinjaToBottomRight() {
let x = (frame.maxX - ninja.frame.width / 2)
let y = (frame.maxY - ninja.frame.height / 2)
ninja.center = CGPoint(x: x, y: y)
}
在这种情况下,您必须先阅读所有行,然后才能了解该功能的实际功能。同样,对于如此短的功能,它几乎没有什么区别,但它需要更长的时间才能让读者更长时间地访问正在发生的事情。
如果闭包内的代码有特定用途,我建议仅使用此函数样式。在这种情况下,它正在创建CGPoint
。如果闭包中的代码引起了诸如播放声音或更新用户界面等副作用,那么我相信第二个示例使用的命令式样式更有意义。
答案 1 :(得分:0)
支撑表达式后的parens被称为立即调用闭包,并具有在大括号内执行闭包的效果。
该样式通常用于初始化,它有助于您创建具有复杂初始化的属性:
public let ninja: UIImageView = {
let image = UIImage(named: "ninja")
let view = UIImageView(image: image)
view.frame = CGRect(x: 0, y: 0, width: 45, height: 39)
return view
}()
如您所示,在函数内使用它没有技术用途。除非编译器能够将其优化为更简单的逻辑,否则它可能效率低。
它与样本中其他地方的变量初始化方式保持一致(假设您正在查看我找到的相同代码)。
在C编程中,通常只使用一对大括号来提供变量的本地范围。这是一种强大的编程实践,可确保它们不会在方法中进一步使用。
如果你想要实现这样的范围,那么Swift成语就是使用do { ...}
。
所以,要明确的是,你正在看的功能可以写得很清楚
public func moveNinjaToBottomRight() {
let x = (frame.maxX - ninja.frame.width / 2)
let y = (frame.maxY - ninja.frame.height / 2)
ninja.center = CGPoint(x: x, y: y)
}
甚至
public func moveNinjaToBottomRight() {
ninja.center = CGPoint(
x: (frame.maxX - ninja.frame.width / 2),
y: (frame.maxY - ninja.frame.height / 2))
}
或者,如果有更多的逻辑,他们想要本地范围。
public func moveNinjaToBottomRight() {
do {
let x = (frame.maxX - ninja.frame.width / 2)
let y = (frame.maxY - ninja.frame.height / 2)
ninja.center = CGPoint(x: x, y: y)
}
// more code here which wants to use x and y names
// but is not reusing the variables above
}