2014-06-10 7 views
37

Ho sempre pensato che funzioni e metodi fossero gli stessi, fino a quando non imparavo Swift attraverso l'eBook "Swift Programming Language". Ho scoperto che non posso usare greet("John", "Tuesday") per chiamare una funzione che ho dichiarato all'interno di una classe, come mostrato nel eBook nella schermata qui sotto:Quali sono le differenze tra funzioni e metodi in Swift?

function declaration in swift

ho ricevuto un errore che dice che "mancante label argomento 'giorno:' in call "di cui al presente screen shot:

Error message in swift

Ecco il codice: -

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

Dopo alcune ricerche, ho trovato questo post: Difference between a method and a function, e mi sembra che la funzione che ho dichiarato all'interno di una classe sia in realtà chiamata un metodo. Quindi, la sintassi che uso per chiamare il metodo è diversa rispetto alla sintassi che uso per chiamare una funzione.

Non ho mai capito questa differenza quando stavo programmando in Objective-C.

  1. Quali sono le differenze tra funzioni e metodi in Swift?

  2. Quando usiamo le funzioni e quando usiamo i metodi in Swift?

+0

possibile duplicato di [Swift : label argomento mancante 'xxx' in chiamata] (http://stackoverflow.com/questions/24050844/swift-missing-argument-label-xxx-in-call) – user3386109

+2

Non penso che sia completamente duplicato dal sopra la domanda. Spero che questa domanda possa chiarire tutti i dubbi tra metodi e funzioni in Swift. Come apparentemente, questo è abbastanza nuovo per me. E penso che potrebbe essere nuovo anche per altri sviluppatori iOS. – Ricky

risposta

36

Dopo un paio d'ore di lettura e sperimentare, qui sono le cose che ho scoperto: -

Funzioni a Swift

funzioni sono blocchi indipendenti di codice che eseguono una determinata compito. Si assegna a una funzione un nome che identifica ciò che fa e questo nome viene utilizzato per "chiamare" la funzione per eseguire il proprio compito quando è necessario .

Resource: Official Apple Documentation on Functions in Swift

Funzione nomi dei parametri

Tuttavia, questi i nomi dei parametri vengono utilizzati solo all'interno del corpo della funzione in sé, e non può essere usato quando si chiama il funzione. Questi tipi di nomi di parametri sono noti come nomi di parametri locali, poiché sono disponibili solo per l'utilizzo all'interno del corpo della funzione.

Significa che per default, tutti i parametri di funzione sono parametri locali.

Ma, a volte, vogliamo indicare lo scopo di ciascun parametro. Pertanto, possiamo definire un nome di parametro esterno per ciascun parametro. Esempio di codice:

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

Un altro modo per rendere il nome del parametro esterno sta usando simbolo cancelletto (#) per abbreviare il nome.

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

per chiamare le funzioni di cui sopra con il parametro esterno, è possibile utilizzare

someFunction(localParameterName:10) 

Metodi a Swift

I metodi sono funzioni che sono associate a un determinato tipo. Classi, strutture ed enumerazioni possono tutti definire i metodi di istanza, che incapsulano attività e funzionalità specifiche per lavorare con un'istanza di un determinato tipo.

Resource: Official Apple Documentation on Methods in Swift

Tuttavia, il comportamento predefinito di nomi locali e nomi esterni è diverso per funzioni e metodi.

particolare, Swift dà il nome parametro in un metodo un nome parametro locale di default, e dà la seconda e le successive nomi dei parametri Entrambi i nomi dei parametri locali ed esterni di default.

codice qui sotto mostra le differenze di impostazione predefinita e dei parametri non predefiniti per il metodo a 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)." 
    } 
} 

Potrei perdere alcuni dettagli importanti. Spero che qualcuno possa fornire una risposta migliore.

+0

Credo che l'uso di # sia disponibile in Swift 2.0+ così come la differenza tra metodi e funzioni. – Johan

+0

#Gatada Buono. Anche l'intera idea di nomi di parametri interni ed esterni diversi è davvero stupida. Fai come in C# dove può essere specificato o meno, per parametro, come piace al chiamante. –

+0

Davvero molto degno @Ricky +1 – Kamarshad

24

Come hai detto tu stesso, i metodi sono funzioni, ma in una classe. In obiettivo-c non te ne sei mai reso conto, perché stavamo codificando solo in classi. Ogni funzione che abbiamo scritto era un metodo di una classe (ViewController o qualche altra classe che abbiamo creato).

In Swift abbiamo la possibilità di creare funzioni che non sono all'interno di una classe. La ragione principale per farlo è scrivere funzioni che non sono legate a nessuna classe e possono essere utilizzate ovunque ne abbiamo bisogno. Quindi, se si dispone di una funzione che è legato ad una classe si scrive all'interno della classe e si può accedere è da ogni istanza della classe:

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

Ma se avete bisogno di accedere alla funzione da ogni dove, poi non lo scrivi all'interno di una classe. Per esempio:

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

Circa i problemi di sintassi tra funzioni e metodi: Avete indovinato giusto, i metodi e le funzioni sono chiamati un po 'diverso. Questo perché in Objective-C avevamo nomi di metodi lunghi e ci piacevano perché potevamo leggere quello che stavano facendo i metodi e per cosa erano i parametri. Quindi il primo parametro di un metodo è nella maggior parte dei casi descritto dal nome della funzione stesso. E gli altri parametri non dovrebbero essere solo numeri, stringhe o istanze, ma dovrebbero anche essere descritti, quindi Swift scrive automaticamente il nome della variabile.Se si vuole descrivere da soli si può fare anche questo:

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

"... in obiettivo-c non te ne sei mai reso conto, perché stavamo codificando solo in classi". In realtà, Objective-C è uno stretto superset di C, ed è del tutto possibile (e utile) avere funzioni "libere", anche nei file .m. A volte è necessario definire un processo che non è legato a nessuna classe. –

+4

Hai ragione. Ma la logica effettiva che è stata utilizzata nello sviluppo di iOS è stata scritta in classi nel 99,999%;) – Ben

+0

Grazie a @ andyvn22 per la correzione! – Ben

1

someFile.swift:

func someFunc{ 
//some code 
} 

class someClass{ 

    func someMethod{ 
    //some code  
    } 

} 

Nota: someClass = somefile

someMethod funziona solo sul suo tipo associato che è 'someClass'. Tuttavia lo stesso non si può dire per someFunc. someFunc è solo in someClass.Swift perché semanticamente è più adatto per essere scritto in quel file. Potrebbe essere stato scritto in qualsiasi altra classe fintanto che è contrassegnato con private

3

Bene, la risposta di @ Ricky lo dice più o meno. Ero confuso cosa fossero esattamente. Così qui è il mio pensiero:

funzioni potrebbero essere definiti al di fuori delle classi o all'interno di classi/struct/enumerazioni, mentre i metodi devono essere definite all'interno di e parte di classi/struct/enumerazioni.

Potremmo definire una funzione al di fuori della definizione di qualsiasi tipo e potremmo utilizzarla all'interno dei metodi della definizione di qualsiasi tipo.

Solo la mia comprensione e illustrazione qui, spero che questo aiuta a qualcun altro o si può modificare se pensate che ci sia un miglioramento necessario o farmi sapere se qualcosa è sbagliato:

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