【问题标题】:SWIFT Syntax question with regards to a CLOSURE关于 CLOSURE 的 SWIFT 语法问题
【发布时间】:2020-06-07 09:13:34
【问题描述】:

也许有人可以向我解释这个sn-p

raywenderlich 上有这个关于核心图形的不错的教程。不幸的是,该页面上的 cmets 已关闭

作者声明

//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?如果是这样,你能说明它是如何使用的吗?
  • 我建议再次阅读Closure Expression Syntax(graphPoint: Int) 是闭包参数,与var graphPoints 无关。
  • 你也可以阅读这篇精彩的文章learnappmaking.com/closures-swift-how-to
  • @Sweeper done -> Martin Mickael,我读过docs.swift.org/swift-book/LanguageGuide/Closures.html,但是,我仍然没有真正理解这个示例,因为它不适用于现有阵列。但我现在将研究 Mickael 的参考文献
  • 我想,我明白了。此闭包不直接应用于数组。相反,它将一个函数存储在一个变量中,然后将其应用于 graphPoints 数组 - 对吗?

标签: swift closures core-graphics


【解决方案1】:

正如您正确识别的那样,这是一个闭包(放入名为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
}

为什么作者写了一个闭包并把它放入一个变量中,而不是写一个函数?我不知道,因为我不会读心术。这是作者的风格选择。

如果你看看它是如何被调用的,这个函数/闭包会计算条的 Y 坐标,给定条的高度,graphPointgraphPoint是函数的参数,所以在剩下的代码中当然没有用到。从调用者可以看出:

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

将为graphPoints 中的每个元素调用columnYPoint,因此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
}

【讨论】:

  • 谢谢@sweeper!我非常专注于数组操作,以至于我错过了闭包可以是分配给变量的函数的解释。虽然我曾经在 25 年前想出了如何在 C 语言中将函数分配给指针,这几乎是相同的概念......
猜你喜欢
  • 1970-01-01
  • 2011-03-17
  • 1970-01-01
  • 1970-01-01
  • 2017-03-23
  • 2021-05-15
  • 2021-05-09
  • 2012-08-11
  • 1970-01-01
相关资源
最近更新 更多