SWIFT 关于 CLOSURE 的语法问题

SWIFT Syntax question with regards to a CLOSURE

也许有人可以向我解释一下这个片段

raywenderlich 上有关于 Core Graphics 的精彩教程。不幸的是,该页面上的评论已关闭

作者声明

//Weekly sample data
var graphPoints = [4, 2, 6, 4, 5, 8, 3]

注意 graphPoints 末尾的 "s"。然后,为了计算包含此类图形的图表的 y 坐标,他在闭包中使用了 graphPoint(末尾没有 "s")。尽管如此,代码运行得很好让我感到困惑。

// calculate the y point

let topBorder = Constants.topBorder
let bottomBorder = Constants.bottomBorder
let graphHeight = height - topBorder - bottomBorder
let maxValue = graphPoints.max()!
let columnYPoint = { (graphPoint: Int) -> CGFloat in
  let y = CGFloat(graphPoint) / CGFloat(maxValue) * graphHeight
  return graphHeight + topBorder - y // Flip the graph
}

并且在这个项目中没有进一步使用 graphPoint(据我所知,使用 "find")。所以我想知道,带有 "s" 的 graphPoints 如何链接到 columnYPoint.

虽然我目前不知道 y 值如何流入闭包,但我已经扩展了我的问题:如果我的值在具有结构 [[x1, x2], [y1, y2] 的二维数组中], 我如何只将我的 y(或只有我的 x)值传递到这个闭包中?

干杯!

更新 这就是使用 columnYPoint 绘制图形的方式:

// draw the line graph

UIColor.white.setFill()
UIColor.white.setStroke()

// set up the points line
let graphPath = UIBezierPath()

// go to start of line
graphPath.move(to: CGPoint(x: columnXPoint(0), y: columnYPoint(graphPoints[0])))

// add points for each item in the graphPoints array
// at the correct (x, y) for the point
for i in 1..<graphPoints.count {
  let nextPoint = CGPoint(x: columnXPoint(i), y: columnYPoint(graphPoints[i]))
  graphPath.addLine(to: nextPoint)
}
graphPath.stroke()

如您正确识别的那样,这是一个闭包(放入名为 columnYPoint 的变量中,为其命名):

let columnYPoint = { (graphPoint: Int) -> CGFloat in
  let y = CGFloat(graphPoint) / CGFloat(maxValue) * graphHeight
  return graphHeight + topBorder - y // Flip the graph
}

真的,它就像一个叫做 columnYPoint:

的函数
func columnYPoint(_ graphPoint: Int) -> CGFloat {
    let y = CGFloat(graphPoint) / CGFloat(maxValue) * graphHeight
    return graphHeight + topBorder - y // Flip the graph
}

为什么作者写了一个闭包放到一个变量中,而不是写一个函数呢?我不知道,因为我不会读心术。这是作者的文体选择。

如果你看看它是如何被调用的,这个 function/closure 计算柱的 Y 坐标,给定柱的高度,graphPointgraphPoint是函数的参数,所以后面的代码当然不用了。从调用者那里可以看出:

graphPath.move(to: CGPoint(x: columnXPoint(0), y: columnYPoint(graphPoints[0])))
// and
let nextPoint = CGPoint(x: columnXPoint(i), y: columnYPoint(graphPoints[i]))

columnYPoint 将为 graphPoints 中的每个元素调用,因此 graphPoint 将是 graphPoints 中的每个值。毕竟我们需要计算每根柱子的坐标。

似乎还有一个前面提到的 columnYPoint 闭包,它计算给定柱索引的 X 坐标。您可以将这两个闭包组合起来,得到一个单一的闭包,它给您一个 CGPoint:

let margin = Constants.margin
let graphWidth = width - margin * 2 - 4
let topBorder = Constants.topBorder
let bottomBorder = Constants.bottomBorder
let graphHeight = height - topBorder - bottomBorder
let maxValue = graphPoints.max()!
let columnPoint = { (column: Int, graphPoint: Int) -> CGPoint in
    //Calculate the gap between points
    let spacing = graphWidth / CGFloat(self.graphPoints.count - 1)
    let x = CGFloat(column) * spacing + margin + 2
    let y = CGFloat(graphPoint) / CGFloat(maxValue) * graphHeight
    return CGPoint(x: x, y: graphHeight + topBorder - y) // Flip the graph
}