【问题标题】:Swift clean code with nested functions带有嵌套函数的 Swift 干净代码
【发布时间】:2016-05-27 20:00:05
【问题描述】:

在使用嵌套函数时,我对当前的代码风格不满意。

什么时候使用嵌套函数?

假设我有一个带有一个参数的函数。论证需要被证实。我会使用它来保护它。现在,您可以将方法中的任务拆分为更小的方法。这样每个方法最多有 n 行。您可以将提取的方法设为私有,但这将是我需要的更大范围。因为这些方法仅在该方法中使用。我可以使用的最小范围是嵌套函数。

但在我看来,代码在嵌套函数时会变脏。

下面的例子展示了我当前的代码风格。

private func myFunction(iterationCount: Int) {
    func nestedOne() {

    }
    func nestedTwo(param: Int) {

    }
    guard iterationCount > 0 else {
        return
    }
    for i in 0 ..< iterationCount {
        nestedOne()
        nestedTwo(i)
    }
}

您如何看待这种代码风格?

编辑:


这是一个真实的例子。这应该是足够的信息。每个方法本身只有几行代码。但是所有这些代码都有很多行。但是将它们设为私有将使它们可以被班级访问。而且这些方法永远不会被其他方法使用。

private func rotateToPoint(newCenterPoint centerPoint: CGPoint, withDuration duration: Double) -> Bool {
    func createAnimation(/*n params here*/) -> CAKeyframeAnimation {
        let animation = CAKeyframeAnimation(keyPath: "position")
        // Create a CAKeyframeAnimation with the given path, duration etc.
        //
        //
        // Method has about this numer of lines.
        //
        //
        return animation
    }
    func createPathForRotation(/*n params here*/) -> UIBezierPath {
        let path = UIBezierPath()
        // Calculcate the path to move a view with an rotating second view.
        //
        //
        // Method has about this number of lines.
        //
        //
        //
        return path
    }
    func completionAction(/*n params here*/) {
        // Update state etc.
        //
        // Method has about this number of lines.
        //
        //
    }
    guard true /* check here */ else {
        return false
    }
    // Some variables and method calls here.
    //
    // Method has about this number of lines.
    //
    //
    //
    //
    return true
}

【问题讨论】:

  • 请描述 nestedOnenestedTwo 应该做什么,以便我提供上下文答案。
  • 添加了一个真实的例子
  • 我看不出你在那里写的有什么问题——或者说是对的。人们对什么是干净什么是脏有不同的看法。像“每个方法最多有 n 行”这样的硬规则是不好的,总是需要灵活性。
  • 假设您希望您的代码完全可测试 - 那么您如何测试嵌套函数?它们在概念上是遥不可及的。还有立即执行的 lambdas 或未命名的函数(在其他语言中,不知道 swift 但假设有类似的东西)等等。所以为什么不问问题“是否有任何不需要测试的函数”?如果是这样,那为什么不声明呢?如果您希望您的代码完全可测试,是否有可能拥有这样的功能?

标签: swift coding-style nested-function


【解决方案1】:

由于您的内部函数用于创建值,您可以使用闭包来初始化和设置变量/常量。

private func rotateToPoint(newCenterPoint centerPoint: CGPoint, withDuration duration: Double) -> Bool {
    guard true /* check here */ else {
        return false
    }

    let animation : CAKeyframeAnimation = {
        let animation = CAKeyframeAnimation(keyPath: "position")
        // set animation properties...
        return animation
    }()

    let path: UIBezierPath = {
        let path = UIBezierPath()
        // seth path properties
        return path
    }()

    let completion: (String)->() =  { (word:String)->() in

    } // <- IMPORTANT! no parenthesis here

    // just use animation, path and completion

    return true
}

如你所愿

  1. 在闭包内声明的变量/常量对rotateToPoint 不可见
  2. 使用闭包创建的变量/常量在rotateToPoint 之外不可见
  3. 恕我直言,代码更干净

【讨论】:

    猜你喜欢
    • 2016-08-23
    • 2013-04-01
    • 1970-01-01
    • 2021-07-11
    • 1970-01-01
    • 1970-01-01
    • 2014-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多