What are the differences between functions and methods in Swift?
Asked Answered
A

7

51

I always thought functions and methods were the same, until I was learning Swift through the "Swift Programming Language" eBook. I found out that I cannot use greet("John", "Tuesday") to call a function that I declared inside a class, as shown in the eBook in the screen shot below:

function declaration in swift

I received a error saying that "Missing argument label 'day:' in call" as per this screen shot:

Error message in swift

Here is the code:-

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

After some research, I found this post: Difference between a method and a function, and it seems to me that the function that I declared inside a class is actually called a method. So, the syntax that I use to call the method is different compared to the syntax that I use to call a function.

I never realized this difference when I was programming in Objective-C.

  1. What are the differences between functions and methods in Swift?

  2. When do we use functions and when do we use methods in Swift?

Alfrediaalfredo answered 10/6, 2014 at 5:59 Comment(2)
possible duplicate of Swift : missing argument label 'xxx' in callRhoea
I don't think it is entirely duplicate from the the above question. I hope that this question can clear up all the doubts between methods and functions in Swift. As apparently, this is quite new to me. And I think it might be new to some other iOS developers as well.Alfrediaalfredo
A
44

After a few hours of reading and experimenting, here are the things that I found out:-

Functions in Swift

Functions are self-contained chunks of code that perform a specific task. You give a function a name that identifies what it does, and this name is used to “call” the function to perform its task when needed.

Resource: Official Apple Documentation on Functions in Swift

Function Parameter Names

However, these parameter names are only used within the body of the function itself, and cannot be used when calling the function. These kinds of parameter names are known as local parameter names, because they are only available for use within the function’s body.

It means that by default, all the parameters for Function are local parameters.

But, sometimes we want to indicate the purpose of each parameter. So, we can actually define an external parameter name for each parameter. Example Code:

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

Another way to make the external parameter name is using hash symbol (#) to shorten the name.

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

To call the above functions with external parameter, you may use

someFunction(localParameterName:10)

Methods in Swift

Methods are functions that are associated with a particular type. Classes, structures, and enumerations can all define instance methods, which encapsulate specific tasks and functionality for working with an instance of a given type.

Resource: Official Apple Documentation on Methods in Swift

However, the default behavior of local names and external names is different for functions and methods.

Specifically, Swift gives the first parameter name in a method a local parameter name by default, and gives the second and subsequent parameter names both local and external parameter names by default.

Code below shows the differences for default and non-default parameters for method in 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)."
    }
}

I might miss some important details. Hope someone can provide a better answer.

Alfrediaalfredo answered 10/6, 2014 at 8:23 Comment(4)
I do believe the use of # is out in Swift 2.0+ as well as the difference between methods and functions.Mudra
#Gatada Good. Also the whole idea of different internal and external parameter names is really dumb too. Just do it like in C# where it can be specified or not, per parameter, as the caller likes.Kaveri
REally very worthfull @Alfrediaalfredo +1Barbellate
I believe externalParameterName should be argumentLabel as official namingGere
W
27

As you said yourself, methods are functions, but in a class. In objective-c you never realized this, because we were only coding in classes. Every function that we wrote was a method of a class (ViewController or some other class we created).

In Swift we have the ability to create functions that are not inside some class. The main reason for doing this is to write functions that are not tied to any class, and can be used wherever we need them. So if you have a function that is related to a class you write it inside the class and you can access is from every instance of the class:

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

But if you need to access the function from everywhere, then you don't write it inside a class. For example:

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

About your syntax issues between functions and methods: You guessed it right, methods and functions are called a little bit differently. That is because in Objective-C we had long method names and we liked them because we could read what the methods were doing and what the parameters were for. So the first parameter in a method is in most cases described by the function name itself. And the other parameters shouldn't only be some numbers or strings or instances, they should be described as well, so Swift writes the name of the variable automatically. If you want to describe it by yourself you can do that as well:

class Something {
    func desc(firstString string1: String, secondString string2:String) {...}
}
Weighty answered 10/6, 2014 at 6:6 Comment(3)
"...in objective-c you never realized this, because we were only coding in classes". Actually, Objective-C is a strict superset of C, and it is quite possible (and useful) to have "free" functions, even in .m files. Sometimes you need to define a process that isn't tied to any class.Nivernais
You are right. But the actual logic that got used in iOS development were written in classes in 99.999% ;)Weighty
Always feels very weird to me writing a c-style function that does Objective-C things, like int f (NSString* p).Dollar
R
11

Mainly the names are used interchangeably without people having a real intent of distinguishing them. But ultimately they do have a difference.

someFile.swift:

func someFunc{
//some code
}

class someClass{

    func someMethod{
    //some code    
    }

}

Note: someClass != someFile

someMethod works only on its associated type which is 'someClass'. However the same can't be said for someFunc. someFunc is only in the someClass.Swift because semantically it is better suited to be written in that file. It could have been written in any other class as long as it's marked with private

And obviously the method can access self. With functions, there is no self.. For more see: What's the difference between a method and a function?

Reluctance answered 4/8, 2016 at 20:46 Comment(0)
T
11

Well, @Ricky's answer says it pretty much. I was confused what exactly they are. So here is my thought:

Functions could be defined outside of classes or inside of classes/structs/enums, while Methods have to be defined inside of and part of classes/structs/enums.

We could define a Function outside of any Type's definition and could use it within Methods of any Type's definition.

Just my understanding and illustration here, hope this helps someone else or you may edit if you feel there is an improvement needed OR let me know if anything is wrong:

//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)
Tenth answered 27/9, 2016 at 21:4 Comment(0)
I
2

functional principle as a part of functional language

function is a first-class type (first-class citizen) in Swift. Higher order functions

  • assign to a variable
  • pass as an argument
  • return

Function

Function is a block of code that is created for executing some task. Function consists of name, optional parameters(name, type), optional return type, body.

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

Function type - function’s parameter type + return type[Java about]. For example it is used as function's parameter

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

Method

Method - is a function which is associated with a type - class, structure, enum [About]:

Instance method - method which belongs to instance

MyClass().foo()

Type method - method which belongs to type itself. class or static is used[About]

MyClass.foo()

Closure

As official doc says that Closure in Swift has three next forms:

  • global function(with name, without capturing) - is a function that is declared in a global scope(out of class scope). Usually it is defined as a first level of .swift file and does not have a big memory foot print
  • nested function(with name, with capturing enclosing function variables) - function inside other function
  • closure expression(without name, with capturing enclosing context)

Closure(closure expression) - anonymous function - is a block of code(functionality). Closure is a type of function without name. Closure is a function in terms of Functional programming. It can support capturing concept(if it doesn't capture it is lambda). It is similar to block in Objective-C.

[Closure vs Lambda]

They can be used for:

  • non-escaping closure - sync operations - click events, sort...
  • escaping closure - async operations - e.g.completion handler - it is a callback/notification which is called when task is done
class ClassA {
    var variable = "Hello"

    func fooA() {
        print(variable)
        let b = ClassB() //1
        b.fooB(completionHandler: { [weak self] (input) -> String? in //2 pass closure //3 capture list or any calls from closure to outher scope
            guard let self = self else { return nil }
            self.variable = "World" //capturing self.variable
            
            return String(input)
        })
    }
}

class ClassB {
    var myCompletionHandler: ((Int) -> String?)? = nil //5
    func fooB(completionHandler: @escaping (Int) -> String?) { //4
        self.myCompletionHandler = completionHandler //6
        let result = completionHandler(7)
    }
    
    func fooB2(completionHandler: @escaping (Int) -> String?) { //if you re-pass function to @escaping function you must mark it by @escaping too
        self.fooB(completionHandler: completionHandler)
    }
}

func testClosure() {
    ClassA().fooA()
}
(Int) -> String? //Function type

//Closure Expression 
{ [weak self] (input) -> String? in 
    //logic
}

[non-escaping vs escaping closure]
[@autoclosure] [Init/customize stored property by closure]

[JVM Memory model]

Interleaf answered 2/4, 2020 at 9:24 Comment(0)
L
1

Here is a simple answer on the difference between functions and methods:

Some folks use “function” and “method” interchangeably, but there’s a small difference: both of them are reusable chunks of code, but methods belong to classes, structs, and enums, whereas functions do not.

So:

func thisIsAFunction() {
}

struct Person {
    func thisIsAMethod() {
    }
}

Because methods always belong to a data type, they have a concept of self that functions do not.

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

Ladysmith answered 6/9, 2018 at 8:28 Comment(0)
R
1

Lots of great answers, but let me use Xcode to show something visually from the UIKit module:

enter image description here

That is a function because it's written at the global level. It's not a method. Methods are scoped to a class.

Screenshot to show that it's at the global level.

enter image description here

The following function is at the global level:

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

Icons for the different symbols. (Class, Method, Property, Protocol, Function, Extensions are all different symbols)

  • The function has an icon like 𝓯
  • The method has an icon of M
Reluctance answered 7/4, 2021 at 14:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.