In Swift, What Does the ! Symbol Mean in a Function Signature

In Swift, what does the ! symbol mean in a function signature?

This isn't quite a duplicate — there's some subtlety to implicitly unwrapped optionals in function signatures beyond their usage elsewhere.

You see implicitly unwrapped optionals in API imported from ObjC because that's the closest Swift approximation of an object that's expected to be there but which can be nil. It's a compromise for imported API — you can address these variables directly like in ObjC, and you can test them for nil using Swift optional syntax. (There's more about Apple's rationale for this in the Advanced Interoperability talk from WWDC14.) This pattern also applies to the IBAction declarations inserted by Interface Builder, since those methods are in effect getting called from ObjC code, too.

As you seem to have suspected, Swift wraps the possible nil in an optional when bridging from ObjC, but the ! in your function implementation's declaration unwraps the value so you can use it directly. (At your own risk.)

Since Swift 1.2 (Xcode 6.2 in Spring 2015), ObjC APIs can be annotated with nonnull and nullable, in which case the Swift interface to those APIs uses either a non-optional type or a fully optional type. (And since Swift 2.0 / Xcode 7.0, nearly all of Apple's APIs are audited to use nullability annotations, so their Swift signatures don't use much ! anymore.)

What's less well-known about this is that you're free to change the optionality of parameters when you implement your own Swift functions that get called by ObjC. If you want the compiler to enforce that sender in your action method can never be nil, you can take the ! off the parameter type. If you want the compiler to make sure you always test the parameter, change the ! to a ?.

What is the meaning of the : in Swift function signatures and why is there no comma when it seems there should be one?

The convention, frequently seen in documentation, is a concise way of referring to a function, using only the function name and argument labels.

So consider this function declaration:

func insert(_ objects: [Any], at indexes: IndexSet)

This is

  • a method called insert;
  • the first parameter name is called objects, this parameter has no argument label (designated with the _) and has a type of [Any]; and
  • the second parameter name is indexes, its argument label is at and has a type of IndexSet.

So you call it like so:

insert(someObjects, at: someIndex)

When you call it, you don’t care what the parameter names that are used inside that function, but rather just what the argument labels are. So, the convention when referring to that method in documentation is to omit the parameter names and types and just use the function name and the argument labels, but no comma:

insert(_:at:)

Note, you’d never actually use this syntax in your code. This is just a documentation convention employed to distill long function declarations down to something more manageable and concise:

transition

For more information about argument labels and parameter names, see Function Argument Labels and Parameter Names

What does an exclamation mark mean in the Swift language?

What does it mean to "unwrap the instance"? Why is it necessary?

As far as I can work out (this is very new to me, too)...

The term "wrapped" implies we should think of an Optional variable as a present, wrapped in shiny paper, which might (sadly!) be empty.

When "wrapped", the value of an Optional variable is an enum with two possible values (a little like a Boolean). This enum describes whether the variable holds a value (Some(T)), or not (None).

If there is a value, this can be obtained by "unwrapping" the variable (obtaining the T from Some(T)).

How is john!.apartment = number73 different from john.apartment = number73? (Paraphrased)

If you write the name of an Optional variable (eg text john, without the !), this refers to the "wrapped" enum (Some/None), not the value itself (T). So john isn't an instance of Person, and it doesn't have an apartment member:

john.apartment
// 'Person?' does not have a member named 'apartment'

The actual Person value can be unwrapped in various ways:

  • "forced unwrapping": john! (gives the Person value if it exists, runtime error if it is nil)
  • "optional binding": if let p = john { println(p) } (executes the println if the value exists)
  • "optional chaining": john?.learnAboutSwift() (executes this made-up method if the value exists)

I guess you choose one of these ways to unwrap, depending upon what should happen in the nil case, and how likely that is. This language design forces the nil case to be handled explicitly, which I suppose improves safety over Obj-C (where it is easy to forget to handle the nil case).

Update:

The exclamation mark is also used in the syntax for declaring "Implicitly Unwrapped Optionals".

In the examples so far, the john variable has been declared as var john:Person?, and it is an Optional. If you want the actual value of that variable, you must unwrap it, using one of the three methods above.

If it were declared as var john:Person! instead, the variable would be an Implicitly Unwrapped Optional (see the section with this heading in Apple's book). There is no need to unwrap this kind of variable when accessing the value, and john can be used without additional syntax. But Apple's book says:

Implicitly unwrapped optionals should not be used when there is a possibility of a variable becoming nil at a later point. Always use a normal optional type if you need to check for a nil value during the lifetime of a variable.

Update 2:

The article "Interesting Swift Features" by Mike Ash gives some motivation for optional types. I think it is great, clear writing.

Update 3:

Another useful article about the implicitly unwrapped optional use for the exclamation mark: "Swift and the Last Mile" by Chris Adamson. The article explains that this is a pragmatic measure by Apple used to declare the types used by their Objective-C frameworks which might contain nil. Declaring a type as optional (using ?) or implicitly unwrapped (using !) is "a tradeoff between safety and convenience". In the examples given in the article, Apple have chosen to declare the types as implicitly unwrapped, making the calling code more convenient, but less safe.

Perhaps Apple might comb through their frameworks in the future, removing the uncertainty of implicitly unwrapped ("probably never nil") parameters and replacing them with optional ("certainly could be nil in particular [hopefully, documented!] circumstances") or standard non-optional ("is never nil") declarations, based on the exact behaviour of their Objective-C code.

What is the meaning of the '#' mark in swift language

Update (Swift 3.*...)

the default behavior of the first parameter’s signature was changed drastically. To understand how argument labels (ex. “external parameters”) and parameter names (ex. “local parameters”) work, please read the chapter “Function Argument Labels and Parameter Names” from the Apple’s Swift-book.

Some examples:

func someFunction(parameterName: Int) { parameterName }
someFunction(parameterName: 5) // argument label not specified

func someFunction(argumentLabel parameterName: Int) { parameterName }
someFunction(argumentLabel: 5) // argument label specified

func someFunction(_ parameterName: Int) { parameterName }
someFunction(5) // argument label omitted

There is no difference in this behavior between methods and functions.


Update (Swift 2.*)

The feature described below was deprecated, one need to write the parameter name twice to get the same behavior as with hash symbol before.


Update (examples)

For functions: when the function is called and purpose of some parameters is unclear, you provide external names for those parameters.

func someFunction(parameterName: Int) { parameterName }
someFunction(5) // What is the meaning of "5"?

func someFunction(externalParameterName parameterName: Int) { parameterName }
someFunction(externalParameterName: 5) // Now it's clear.

But if external and local names are the same, you just write a hash symbol before the parameter name.

func someFunction(#parameterName: Int) { parameterName }
// It's actually like:
// func someFunction(parameterName parameterName: Int) { parameterName }
someFunction(parameterName: 5)

For methods: by default first parameter name is only local (like by functions), but second and subsequent parameter names are both local and external (like as you write a hash symbol before the parameter name, this # is implicitly there):

class SomeClass {
func someMethodWith(firstParameter: Int, andSecondParameter: Int) { ... }
}
SomeClass().someMethodWith(5, andSecondParameter: 10)

You can use # (or add an explicit external name) for the first parameter of the method too, but it'll not match Objective-C-style calling.

class SomeClass {
func someMethodWith(#firstParameter: Int, andSecondParameter: Int) { ... }
}
SomeClass().someMethodWith(firstParameter: 5, andSecondParameter: 10)

Original answer

If you want to provide an external parameter name for a function
parameter, and the local parameter name is already an appropriate name
to use, you do not need to write the same name twice for that
parameter. Instead, write the name once, and prefix the name with a
hash symbol (#). This tells Swift to use that name as both the local
parameter name and the external parameter name.

Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itunes.apple.com/ru/book/swift-programming-language/id881256329?l=en&mt=11

Meaning of - in Swift

The <- operator is not part of Swift.

There's nothing in the Swift manual about it.

It is a custom operator defined by a third-party library you're using in your project.

If you do a CMD-click on it, Xcode should open the operator's declaration

What does an ampersand (&) mean in the Swift language?

It works as an inout to make the variable an in-out parameter. In-out means in fact passing value by reference, not by value. And it requires not only to accept value by reference, by also to pass it by reference, so pass it with & - foo(&myVar) instead of just foo(myVar)

As you see you can use that in error handing in Swift where you have to create an error reference and pass it to the function using & the function will populate the error value if an error occur or pass the variable back as it was before

Why do we use it? Sometimes a function already returns other values and just returning another one (like an error) would be confusing, so we pass it as an inout. Other times we want the values to be populated by the function so we don't have to iterate over lots of return values, since the function already did it for us - among other possible uses.

I hope that helps you!

Swift: When i pass a parameter to a function does the function copies the parameter or uses the reference to that parameter

When you pass a reference type into a swift function you are passing along a reference to that object, so any changes that you make to the object in that method will effect that object outside the function. You can achieve a similar effect for value types if you label them as inout parameters.

What is _: in Swift telling me?

The _ is used to define that the parameter is not named

If you have multiple _ it states that you do not need to name the parameters in your function call

func myFunc(name:String, _ age:String){
}

myFunc(“Milo", "I'm a really old wizard")

If you do not use the underscore you would use

myFunc(“Milo”, age: "I'm a really old wizard")

The _ is not necessary for function calls. It is just used to indicate that something does not need to have a name.

In regards to how you would refer to your function, You would not have to pass any name for the function call.

But since you also don’t define a parameter type this seems to me like an invalid example (it at least doesn’t work in Xcode 7 with Swift 2.0)

Edit:

Since Swift 3.0

myFunc(name: “Milo”, age: "I'm a really old wizard")

Should be used



Related Topics



Leave a reply



Submit