我一直认为函数和方法是一样的,直到我通过“Swift Programming Language”电子书学习Swift。我发现我无法使用greet("John", "Tuesday")
来调用我在类中声明的函数,如下面屏幕截图中的电子书所示:
根据此屏幕截图,我收到错误消息“缺少参数标签'日:'正在通话”:
以下是代码: -
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中的方法?
答案 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() {
}
}
由于方法始终属于数据类型,因此它们具有以下概念: 功能不起作用的自我。
答案 5 :(得分:0)
函数是Swift中的一流类型(一流公民)
Function
是为执行某些任务而创建的代码块。函数由name
,可选parameters(name, type)
,可选return type
,body
组成。
func name(parameterName1: Int, parameterName2: String) -> Bool {
//statements
return true
}
Function type
-函数的parameter type
和return type
//Function type for the sample above
(Int, String) -> Bool
Method
-是与function
-类,结构,枚举[About]相关联的type
:
Instance method
-method
,属于实例
MyClass().foo()
Type method
-method
属于 type 本身。使用了class
或static
[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
}
答案 6 :(得分:0)
很多很棒的答案,但让我使用 Xcode 从 UIKit
模块中可视化显示一些内容:
这是一个函数,因为它是在全局级别编写的。这不是一种方法。方法的作用域是一个类。
显示它在全局级别的屏幕截图。
以下函数是全局级别的:
public func UIApplicationMain(_ argc: Int32, _ argv: UnsafeMutablePointer<UnsafeMutablePointer<Int8>>!,
_ principalClassName: String?, _ delegateClassName: String?) -> Int32
不同符号的图标。 (Class、Method、Property、Protocol、Function、Extensions都是不同的符号)
?
的图标M