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

Posted

技术标签:

【中文标题】Swift 中的函数和方法有啥区别?【英文标题】:What are the differences between functions and methods in Swift?Swift 中的函数和方法有什么区别? 【发布时间】:2014-07-30 19:06:31 【问题描述】:

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

根据此屏幕截图,我收到一条错误消息,提示“缺少参数标签 'day:' in call”:

这里是代码:-

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 编程时从未意识到这种差异。

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

    我们什么时候使用函数,什么时候在 Swift 中使用方法?

【问题讨论】:

Swift : missing argument label 'xxx' in call的可能重复 我不认为它与上述问题完全重复。我希望这个问题能够解开 Swift 中方法和函数之间的所有疑惑。显然,这对我来说很新鲜。而且我认为这对其他一些 ios 开发人员来说可能也是新事物。 【参考方案1】:

正如您自己所说,方法是函数,但在类中。在 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) ...

【讨论】:

"...在 Objective-c 中你从未意识到这一点,因为我们只是在类中编码"。实际上,Objective-C 是 C 的严格超集,即使在 .m 文件中,也很有可能(并且有用)拥有“免费”函数。有时您需要定义一个不与任何类绑定的进程。 你是对的。但是在 iOS 开发中使用的实际逻辑 99.999% 是在类中编写的;) 我总是觉得写一个 c 风格的函数来做 Objective-C 的事情很奇怪,比如 int f (NSString* p)。【参考方案2】:

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

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)."
    

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

【讨论】:

我相信# 的使用在 Swift 2.0+ 中已经被淘汰,以及方法和函数之间的区别。 #Gatada 好。此外,不同的内部和外部参数名称的整个想法也很愚蠢。就像在 C# 中一样,可以根据调用者的喜好指定或不指定每个参数。 真的很值得@Ricky +1 我认为externalParameterName应该是argumentLabel作为官方命名【参考方案3】:

主要是名称可以互换使用,而人们并没有真正区分它们的意图。但最终他们确实有区别。

someFile.swift:

func someFunc
//some code


class someClass

    func someMethod
    //some code    
    


注意: someClass != someFile

someMethod 仅适用于其关联类型“someClass”。然而,对于 someFunc 则不能这样说。 someFunc 仅在 someClass.Swift 中,因为 语义 它更适合写入该文件。只要标有private,它就可以在任何其他类中编写

显然该方法可以访问self。有了函数,就没有self.。更多内容见:What's the difference between a method and a function?

【讨论】:

【参考方案4】:

嗯,@Ricky 的回答说得差不多了。我很困惑它们到底是什么。所以这是我的想法:

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

我们可以在任何类型定义之外定义一个函数,并且可以在任何类型定义的方法中使用它。

这里只是我的理解和说明,希望这对其他人有所帮助,或者如果您觉得需要改进,可以进行编辑,或者如果有任何问题,请告诉我:

//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)

【讨论】:

【参考方案5】:

这里简单回答一下函数和方法的区别:

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

所以:

func thisIsAFunction() 


struct Person 
    func thisIsAMethod() 
    

因为方法总是属于一种数据类型,所以它们有一个概念 函数没有的self。

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

【讨论】:

【参考方案6】:

作为函数式语言一部分的函数式原理

函数是 Swift 中的一等类型(一等公民)。高阶函数

分配给变量 作为参数传递 返回

功能

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

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

Function type - 函数的 parameter typereturn type[Java about]

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

方法

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

Instance method - method 属于实例

MyClass().foo()

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

MyClass.foo()

关闭

正如官方文档所说,Swift 中的 Closure 有以下三种形式:

global function(有名称,无捕获) - 是在全局范围内(超出类范围)声明的函数。通常它被定义为.swift文件的第一级,并且没有大内存食物打印 nested function(带名称,带捕获封闭函数变量) - 函数在其他函数中 closure expression(没有名字,有捕获封闭上下文)

所以function 是一个名为closure

Closure(closure expression) - anonymous function - 是一个代码块(功能)。 Closure 是一种没有名称的 functionClosure 在函数式编程方面是 function。它可以支持capturing 概念。类似于 Objective-C 中的block

[Closure vs Lambda]

它们可用于:

非转义闭包 - 同步操作 - 点击事件、排序... 转义闭包 - 异步操作 - 例如完成处理程序 - 它是在任务完成时调用的回调/通知
//declaration
 (<parameters>) -> <return type> in
        //body


let someClosure:() -> () = 
//closure between    


//call
someClosure()

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

【讨论】:

【参考方案7】:

很多很棒的答案,但让我用 Xcode 来展示来自UIKit 模块的东西视觉

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

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

以下函数处于全局级别:

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

不同符号的图标。 (类、方法、属性、协议、函数、扩展都是不同的符号)

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

【讨论】:

以上是关于Swift 中的函数和方法有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

Go中的函数和方法有啥区别?

在 C# 中,类中的析构函数和 Finalize 方法有啥区别?

Objective-C/Swift中定义常量有啥区别?

重载和重写有啥区别

Elixir 中的命名函数和匿名函数有啥区别?

php静态方法-“静态函数”和“公共静态函数”有啥区别?