Swift中的函数和方法有什么区别?

时间:2014-06-10 05:59:40

标签: function methods swift

我一直认为函数和方法是一样的,直到我通过“Swift Programming Language”电子书学习Swift。我发现我无法使用greet("John", "Tuesday")来调用我在类中声明的函数,如下面屏幕截图中的电子书所示:

function declaration in swift

根据此屏幕截图,我收到错误消息“缺少参数标签'日:'正在通话”:

Error message in swift

以下是代码: -

import Foundation
import UIKit

class ViewController2: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        //var dailyStatement = greet("John", "Tuesday")
        var dailyStatement = greet("John", day: "Tuesday")
        println(dailyStatement)
    }

    func greet(name: String, day: String) -> String {
        return "Hello \(name), today is \(day)."
    }
}

经过一番研究,我发现这篇文章:Difference between a method and a function,在我看来,我在一个类中声明的函数实际上被称为方法。因此,与用于调用函数的语法相比,我用于调用方法的语法是不同的。

当我在Objective-C中编程时,我从未意识到这种差异。

  1. Swift中的函数和方法有什么区别?

  2. 我们何时使用函数?何时使用Swift中的方法?

7 个答案:

答案 0 :(得分:41)

经过几个小时的阅读和实验,我发现了以下内容: -

Swift中的函数

  

函数是执行特定代码的自包含代码块   任务。您为函数指定一个名称,以标识它的作用,以及   此名称用于“调用”函数以执行其任务时   需要的。

资源Official Apple Documentation on Functions in Swift

功能参数名称

  

但是,这些参数名称仅用于体内   函数本身,并且在调用函数时不能使用。这些   各种参数名称称为本地参数名称,因为   它们只能在函数体内使用。

这意味着默认情况下,Function的所有参数都是本地参数

但是,有时我们想要指出每个参数的目的。因此,我们实际上可以为每个参数定义外部参数名称。示例代码:

func someFunction(externalParameterName localParameterName: Int) {
    // function body goes here, and can use localParameterName
    // to refer to the argument value for that parameter
}

制作外部参数名称的另一种方法是使用哈希符号(#)来缩短名称。

func someFunction(#localParameterName: Int) {
    // function body goes here, and can use localParameterName
    // to refer to the argument value for that parameter
}

要使用外部参数调用上述函数,可以使用

someFunction(localParameterName:10)

Swift中的方法

  

方法是与特定类型相关联的函数。   类,结构和枚举都可以定义实例方法,   它封装了使用的特定任务和功能   给定类型的实例。

资源Official Apple Documentation on Methods in Swift

  

但是,本地名称和外部名称的默认行为是   功能和方法不同。

     

具体来说,Swift在方法中给出第一个参数名称   默认情况下参数名称,并给出第二个和后续的   默认情况下,参数名称为本地和外部参数名称。

下面的代码显示了Swift中方法的默认和非默认参数的差异。

import Foundation
import UIKit

class ViewController2: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        //Default methods calling
        var dailyStatement = greet("Rick", day: "Tuesday")
        println(dailyStatement)

        //First parameter is also an external parameter
        var dailyStatement2 = greet2(name:"John", day: "Sunday")
        println(dailyStatement2)
    }

    //Default: First Parameter is the local parameter, the rest are external parameters
    func greet (name: String, day: String) -> String {
        return "Hello \(name), today is \(day)."
    }

    //Use Hash symbol to make the First parameter as external parameter
    func greet2 (#name: String, day: String) -> String {
        return "Hello \(name), today is \(day)."
    }
}

我可能会错过一些重要细节。希望有人能提供更好的答案。

答案 1 :(得分:26)

正如你自己所说,方法是功能,但在课堂上。在objective-c中你从未意识到这一点,因为我们只是在课堂上编写代码。我们编写的每个函数都是一个类的方法(ViewController或我们创建的其他类)。

在Swift中,我们能够创建不在某个类中的函数。这样做的主要原因是编写与任何类无关的函数,并且可以在我们需要的任何地方使用。因此,如果你有一个与类相关的函数,你可以在类中编写它,并且可以从类的每个实例访问:

class Square {
   var length: Double
   func area() -> Double {
      return length * length
   }
}

但是如果你需要从任何地方访问该函数,然后你不会在一个类中写它。例如:

func squared(number: Int) -> Int {
    return number * number
}

关于函数和方法之间的语法问题:您猜对了,方法和函数的调用方式略有不同。那是因为在Objective-C中我们有很长的方法名称,我们喜欢它们,因为我们可以读取方法正在做什么以及参数是什么。因此,方法中的第一个参数在大多数情况下由函数名称本身描述。其他参数不仅应该是一些数字或字符串或实例,它们也应该被描述,因此Swift会自动写出变量的名称。如果你想自己描述它,你也可以这样做:

class Something {
    func desc(firstString string1: String, secondString string2:String) {...}
}

答案 2 :(得分:9)

嗯,@ Ricky的回答说得非常好。我很困惑他们到底是什么。所以这是我的想法:

  

函数可以在类之外或类/结构/枚举内定义,而方法必须在类/结构/枚举的内部和部分定义。

     

我们可以在任何Type的定义之外定义一个Function,并且可以在任何Type的定义的Methods中使用它。

这里只是我的理解和插图,希望这可以帮助别人或者你可以编辑,如果你觉得需要改进或者让我知道是否有任何错误:

//This is a Function which prints a greeting message based on the category defined in an 'enum'
func greet(yourName name: String, category: GreetingsCategory) {
    switch  category {
        case .Person:
            print("Hello, " + name + " Today is Tuesday")
        case .Vehicle:
            print("Hello, " + name + " your Vehicle is a Car")
    }
}

//This is an 'enum' for greetings categories
enum GreetingsCategory: String {
    case Person
    case Vehicle
}

//Type: Person
class Person {

    //This is a method which acts only on Person type
    func personGreeting() {
        greet(yourName: "Santosh", category: .Person)
    }
}

//Type: Vehicle
class Vehicle {

    //This is a method which acts only on Vehicle type
    func vehicleGreeting() {
        greet(yourName: "Santosh", category: .Vehicle)
    }
}

//Now making use of our Function defined above by calling methods of defferent types.
let aPerson = Person()
aPerson.personGreeting()
//prints : Hello, Santosh Today is Tuesday

let aVehicle = Vehicle()
aVehicle.vehicleGreeting()
//prints: Hello, Santosh your Vehicle is a Car

//We can also call the above function directly
greet(yourName: "Santosh", category: .Person)

答案 3 :(得分:8)

主要是这些名字可以互换使用,而没有人真正想要区分它们。但最终他们确实有所不同。

<强> someFile.swift

func someFunc{
//some code
}

class someClass{

    func someMethod{
    //some code    
    }

}

注意: someClass!= someFile

someMethod仅适用于其关联类型,即“某些类别”。但是对于someFunc来说却不能说同样的话。 someFunc仅在someClass.Swift中,因为语义它更适合在该文件中编写。它可以写在任何其他类中,只要它标有private

即可

显然,该方法可以访问self。使用函数时,没有self.。有关详情,请参阅:What's the difference between a method and a function?

答案 4 :(得分:1)

关于功能和方法之间的区别,这是一个简单的答案:

  

有些人可以互换使用“功能”和“方法”,但是有一个   差别不大:它们都是可重用的代码块,但是   方法属于类,结构和枚举,而函数属于   不是。

所以:

func thisIsAFunction() {
}

struct Person {
    func thisIsAMethod() {
    }
}
  

由于方法始终属于数据类型,因此它们具有以下概念:   功能不起作用的自我。

来源:https://www.hackingwithswift.com/example-code/language/whats-the-difference-between-a-function-and-a-method

答案 5 :(得分:0)

功能原理作为功能语言的一部分

函数是Swift中的一流类型(一流公民)

  • 分配给变量
  • 通过作为参数
  • 返回

功能

Function是为执行某些任务而创建的代码块。函数由name,可选parameters(name, type),可选return typebody组成。

func name(parameterName1: Int, parameterName2: String) -> Bool {
    //statements
    return true
}

Function type-函数的parameter typereturn type

//Function type for the sample above
(Int, String) -> Bool

方法

Method-是与function-类,结构,枚举[About]相关联的type

Instance method-method,属于实例

MyClass().foo()

Type method-method属于 type 本身。使用了classstatic [About]

MyClass.foo()

关闭

Closure-是功能块。它是支持function概念的capturing。它类似于Objective-C中的block。您还可以发现Closure在功能世界中是Lambda,但是lambda只是一个无名函数,而Closure则复制了非局部变量

Swift中的闭包有以下三种形式:

  • global function(带名称,不捕获)-是在全局范围(超出类范围)中声明的函数。通常,它被定义为.swift文件的第一级,并且没有很大的记忆印记
  • nested function(带有名称,用于捕获封闭的函数变量)-其他函数内部的函数
  • closure expression(不带名称,具有捕获封闭的上下文)
{ (<parameters>) -> <return type> in
      //body
}

[non-escaping vs @escaping closure]
[@autoclosure]

答案 6 :(得分:0)

很多很棒的答案,但让我使用 Xcode 从 UIKit 模块中可视化显示一些内容:

enter image description here

这是一个函数,因为它是在全局级别编写的。这不是一种方法。方法的作用域是一个类。

显示它在全局级别的屏幕截图。

enter image description here

以下函数是全局级别的:

public func UIApplicationMain(_ argc: Int32, _ argv: UnsafeMutablePointer<UnsafeMutablePointer<Int8>>!,
 _ principalClassName: String?, _ delegateClassName: String?) -> Int32

不同符号的图标。 (Class、Method、Property、Protocol、Function、Extensions都是不同的符号)

  • 该函数有一个类似 ? 的图标
  • 该方法的图标为 M