在定义函数之前声明Swift函数

9

如果我在Swift Playground中运行此代码,它可以正常工作。该函数在被调用之前就已经被定义了。

import Cocoa

func addValues(valueA:Double, valueB:Double)
{
    let result = valueB + valueB
    println("Result \(result)")
}

addValues(23.83, 87.12)
如果我在函数定义之前尝试调用函数,就会收到错误消息。这并不出乎意料,因为编译器仍然不知道这个函数。(由于某种原因它似乎仍然有效)
import Cocoa

addValues(23.83, 87.12)

func addValues(valueA:Double, valueB:Double)
{
    let result = valueB + valueB
    println("Result \(result)")
}
在Objective-C中,我可以仅在文件顶部声明函数头,并在代码结尾处定义该函数。因此,我的示例的第二个版本也可以工作。在Swift中我能做到这一点吗?我在文档中没有找到任何信息。
编辑:
andyvn22写道,这只会在playground中发生,而不会在实际项目中发生,所以我尝试了一下。只是一个带有函数的简单命令行工具。我收到了相同的错误,无法编译。如果我将调用移动到函数定义之后,它就可以正常工作。 function

你试过吗? func addValues(Double,Double) - nhgrif
如果我在函数定义之前尝试调用该函数,我会收到错误消息。这并不意外,因为编译器仍然不知道该函数。(由于某种原因,它似乎仍然可以工作),但这个描述有点含糊不清。 - user1804599
如果你尝试这样做,你会得到两个错误(“在函数声明体中缺少'{'”和“无效的重新声明”)。 - David Moles
糟糕——似乎这不是类的问题,但是当直接调用函数时,在游乐场之外仍然存在问题。 - andyvn22
在我的看法中:如果你先访问任何函数再去定义它,编译器就不会在你的代码中继续查找以检查是否已经定义了该函数。这可能是因为苹果不希望 Swift 的编译时间像 Java 一样长。 - Apurva
Swift从来没有要求前置声明,也不关心源文件中函数的顺序。在你的例子中,你的调用点与函数签名不匹配。你漏掉了参数标签。简而言之,这个问题是一个打字错误导致的。 - Rob
1个回答

13

我相信在Swift中,一般情况下不能在函数声明前调用它们,因为它们在此时对编译器来说是未知的。而在Objective C中则不同,因为在头文件中声明函数会将其作为指向函数定义的指针在导入时引入编译器。然后,当调用该函数时,编译器可以引用已导入的指针,从而将其带到文件中的函数定义处。
在Swift中,情况有所不同,因为我们不需要在头文件中声明属性 - 我们在一个文件中同时声明和定义。虽然更简单,但这会创建一个类似于您所遇到的问题,即编译器在其声明/定义之前不知道该函数。
在类中,规则发生了改变,因为我们可以像这样调用函数:

    class HypnosisViewController: UIViewController {

        override func viewDidLoad() {
            // Function call
            addValues(30.0, 40.0) 
        } 

        // Function declaration
        func addValues(valueA:Double, valueB:Double){
            let result = valueB + valueB
            println("Result \(result)")
        }
    }
尽管函数调用在函数声明之后,我们仍然可以这样做。因为当类的一个实例被创建时,该类的所有实例变量和方法都会被初始化为该对象。这意味着编译器已经初始化并因此识别了addValues函数,所以不会有任何投诉。然而,在像Playground这样按顺序执行代码时,我们没有这种初始化方式,因此不可能在函数声明之前调用函数,原因如前所述(编译器不知道该函数)。对于这种情况,Playground的非典型行为对我来说有点含糊不清,因为它会抱怨函数调用在函数声明之前,但它仍然会正确显示调用结果。我相信这是由于Playground编译代码的独特方式造成的。很抱歉我不知道如何在Swift中保留这个Objective C的功能,我知道这是你的问题的一部分。不过,我希望这能让你了解为什么会发生这种情况。

4
我无法相信 Swift 处理不了这个。看起来在2017年我们应该能够引用在同一个文件中稍后声明的函数。 - devios1
“我认为在Swift中,通常不能在函数声明之前调用它们,因为此时编译器不知道它们的存在。”...但事实并非如此。你绝对可以在同一编译单元中稍后定义的函数中调用它们。(据我所知,在Swift中从未出现过这种情况。) - Rob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接