Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift string vs. string! vs. string?

I have read this question and some other questions. But they are somewhat unrelated to my question

For UILabel if you don't specify ? or ! you will get such an error:

@IBOutlet property has non-optional type 'UILabel'

Which then Xcode gives you 2 choices to have it fixed, you can do:

fix-it Add ? to form the optional type UIlabel?
fix-it Add ! to form the implicitly unwrapped optional type UIlabel?

However for string you can just type string without ? or ! and you won't get an error why is that?

What happens if the name isn't set? Then we would have a nil isn't using ?, ! and Swift all about satisfying 'type-safety'?

Example:

struct PancakeHouse {
  let name: String // this doesn't have '?' nor '!'
  let photo: UIImage?
  let location: CLLocationCoordinate2D?
  let details: String
}

My major confussion is when would we want to not use Optional?

like image 887
mfaani Avatar asked May 27 '16 22:05

mfaani


People also ask

What does string mean Swift?

A string is a series of characters, such as "Swift" , that forms a collection. Strings in Swift are Unicode correct and locale insensitive, and are designed to be efficient. The String type bridges with the Objective-C class NSString and offers interoperability with C functions that works with strings.

What is the type of string in Swift?

Swift's String type is a value type. If you create a new String value, that String value is copied when it's passed to a function or method, or when it's assigned to a constant or variable.

How do I combine strings in Swift?

In the apple documentation for swift it states that you concatenate 2 strings by using the additions operator e.g. : let string1 = "hello" let string2 = " there" var welcome = string1 + string2 4 // welcome now equals "hello there"

How do I remove special characters from a string in Swift?

To remove specific set of characters from a String in Swift, take these characters to be removed in a set, and call the removeAll(where:) method on this string str , with the predicate that if the specific characters contain this character in the String.


Video Answer


2 Answers

All this is covered in the documentation: The Swift Programming Language - The Basics.

In short:

String represents a String that's guaranteed to be present. There is no way this value can be nil, thus it's safe to use directly.

String? represents a Optional<String>, which can be nil. You can't use it directly, you must first unwrap it (using a guard, if let, or the force unwrap operator !) to produce a String. As long as you don't force unwrap it with !, this too is safe.

String! also represents an Optional<String>, which can be nil. However, this optional can be used where non-optionals are expected, which causes implicit forced unwrapping. It's like having a String? and having it always be implicitly force unwrapped with !. These are dangerous, as an occurrence of nil will crash your program (unless you check for nil manually).

like image 63
Alexander Avatar answered Oct 06 '22 01:10

Alexander


For your PancakeHouse struct, name is non-optional. That means that its name property cannot be nil. The compiler will enforce a requirement that name be initialized to a non-nil value anytime an instance of PancakeHouse is initialized. It does this by requiring name to be set in any and all initializers defined for PancakeHouse.

For @IBOutlet properties, this is not possible. When an Interface Builder file (XIB or Storyboard) is unarchived/loaded, the outlets defined in the IB file are set, but this always occurs after the objects therein have been initialized (e.g. during view loading). So there is necessarily a time after initialization but before the outlets have been set, and during this time, the outlets will be nil. (There's also the issue that the outlets may not be set in the IB file, and the compiler doesn't/can't check that.) This explains why @IBOutlet properties must be optional.

The choice between an implicitly unwrapped optional (!) and a regular optional (?) for @IBOutlets is up to you. The arguments are essentially that using ! lets you treat the property as if it were non-optional and therefore never nil. If they are nil for some reason, that would generally be considered a programmer error (e.g. outlet is not connected, or you accessed it before view loading finished, etc.), and in those cases, failing by crashing during development will help you catch the bug faster. On the other hand, declaring them as regular optionals, requires any code that uses them to explicitly handle the case where they may not be set for some reason. Apple chose implicitly unwrapped as the default, but there are Swift programmers who for their own reasons, use regular optionals for @IBOutlet properties.

like image 37
Andrew Madsen Avatar answered Oct 06 '22 01:10

Andrew Madsen