Getting Your Feet Wet with Swift: Variables, Constants, and Loops
- Building Blocks of Swift
- Merging Variables into a String
- Optionals: A Gift to Unwrap
- Tuples
- Number Types
- From Objective-C to Swift
- Summary
Swift is a new programming language created by Apple, with the intention of making development of software for Apple products significantly easier. If you have experience in C and Objective-C, you should find Swift to be a walk in the park. All the classes and types that are available to you in C and Objective-C are ported over and available in their exact incarnations in Swift.
If, however, you come from a Ruby or Python background, you will find Swift’s syntax to be right up your alley. Swift borrows and iterates on many ideas from Python and Ruby.
如果你来自JavaScript的世界,你会pleased to know that Swift also doesn’t ask you to declare types, as old strict Java does. You will also be pleased to know that Swift has its own version ofindexOfand many other familiar JavaScript functions. If they aren’t the exact replicas of said functions, they will at least be familiar.
If you come from the Java world, you will be happy to know that even though Swift does not force you to declare types, you still can and Swift most certainly enforces those types, very strictly.
These are all just basic syntax comparisons; the real magic evolves from Swift’s chameleon-like capability to be written in any way that makes you the programmer comfortable. If you want to write the tersest one-liner that does everything you ever needed in one fell swoop, Swift has you covered. If you want to write Haskell-like functional programming, Swift can do that, too. If you want to write beautiful object-oriented programming with classic design patterns, Swift will do that as well.
In the future (or now, depending on when you are reading this), Swift will be open source so that you can officially (theoretically) write Swift on Linux or Windows. Someone may even create a web framework like Ruby on Rails in Swift.
This chapter covers the basic building blocks of Swift. It starts with variables and constants. With this knowledge, you will be able to store whatever you’d like in memory. Swift has a special feature calledoptionals,which allows you to check fornilvalues in a smoother way than in other programming languages. As I briefly mentioned before, Swift has strong type inference; this allows you to have strict typing without needing to declare a type. This chapter also goes over how Swift handles loops andif/elsestatements.
Building Blocks of Swift
Swift allows you to use variables and constants by associating a name with a value of some type. For example, if you want to store the string"Hi"in a variable namedgreeting, you can use a variable or a constant. You create a variable by using thevarkeyword. This establishes an associated value that can be changed during the execution of the program. In other words, it creates a mutable storage. If you do not want mutable storage, you can use a constant. For example, you might record the number of login retries a user is allowed to have before being refused access to the site. In such a case, you would want to use a constant, as shown in this example:
var hiThere = "Hi there" hiThere = "Hi there again" let permanentGreeting = "Hello fine sir" permanentGreeting = "Good morning sir"
Notice that you don’t use a semicolon as you would in many other languages. Semicolons are not mandatory, unless you want to combine many statements together on the same line. In Swift you would not put a semicolon on the end of the line, even though Swift will not complain. Here is an example that shows you when you would use the semicolon in Swift when multiple lines are combined into one:
let numberOfRetries = 5; var currentRetries = 0
Also unique to Swift, you can use almost any Unicode character to name your variables and constants. Developers can name resources using Hebrew, Simplified Chinese, and even special Unicode characters, such as full-color koala emoji.
When declaring multiple variables, you can omit thevarkeyword. Here is an example:
var yes = 0, no = 0
Computed Properties (Getters and Setters)
In Swift you can also declare variables as computed properties. You would use this when you want to figure out the value of the variable at runtime. Here is an example of a getter, where the value of the score is determined by how much time is left. In this example we are creating a read-only computed property.
var timeLeft = 30 var score:Int { get{ return timeLeft * 25 } } print(score)
In this example we can reference (or read)scoreanywhere because it is in the global scope. What is really interesting is that if we try to set the score, it will give us an error because we have created a read-only property. If we want to be able to set this property, we need to create a setter. You cannot create a setter without a getter. Aside from the fact that it would not make sense, it also just will not work. Let’s create a setter to go along with our getter. It does not make sense for a setter to set the computed property directly because the value of the property is computed at runtime. Therefore, you use a setter when you want to set other values as a result of the setter being set. Also, setters work well in some sort of organizational unit, which we haven’t covered yet, but it’s worth diving into briefly. Here is a full Swift example, which includes many elements we have not covered yet.
import UIKit struct Book { var size = CGSize() var numberOfPages = 100; var price:Float { get{ return Float(CGFloat(numberOfPages) * (size.width * size.height)) } set(newPrice){ numberOfPages = Int(price / Float(size.width * size.height)) } } } var book = Book(size: CGSize(width: 0.5, height: 0.5), numberOfPages: 400) print(book.price) book.price = 400 print(book.numberOfPages)
In this example we create a bookStruct, which is a way to organize code so that it is reusable. I would not expect you to understand all of this example, but if you have ever coded in any other languages, you will notice that there is a lot of type casting going on here. Type casting is a something you do all the time in Objective-C and most other languages. We will cover all aspects of this code in this book, but you should know that we created a setter, which sets the number of pages in the book relative to the new price.
Using Comments
You indicate comments in Swift by using a double forward slash, exactly as in Objective-C. Here’s an example:
// This is a comment about the number of retries let numberOfRetries = 5 // We can also put a comment on the end of a line.
If you want to create comments that span multiple lines, you can use this /* */ style of comments, which also works well for documentation.
/* Comments can span multiple lines */
Inference
Swift uses inference to figure out whattypesyou are trying to use. Because of this, you do not need to declare a type when creating variables and constants. However, if you want to declare a type you may do so, and in certain situations, it is absolutely necessary. When declaring a variable, the rule of thumb is that Swift needs to know what type it is. If Swift cannot figure out the type, you need to be more explicit. The following is a valid statement:
var currentRetries = 0
Notice that Swift has to figure out what type of number this is.currentRetriesmay be one of the many types of numbers that Swift offers (Swift will infer this as anInt如果你想知道,但稍后将进行更详细的讨论). You could also use this:
var currentRetries:Int = 0
In this case, you explicitly set the type toIntby using the colon after the variable name to declare a type. Although this is legit, it is unnecessary because Swift already knows that0is anInt. Swift can and will infer a type on a variable that has an initial value.
When do you need to declare the type of a variable or constant? You need to declare the type of a variable or constant if you do not know what the initial value will be. For example:
var currentRetries:Int
In this case, you must declareIntbecause without it, Swift cannot tell what type this variable will be. This is calledtype safety.If Swift expects a string, you must pass Swift a string. You cannot pass anInt当一个String预计。这种风格的编码是一个伟大的时间saver. You will do a lot less typing with your fingers and a lot more thinking with your brain. Every default value you give a variable without a type will be given a type. Let’s talk about numbers first.
For number types, Swift gives us the following:
Intis available in 8, 16, 32, and 64 bits, but you will most likely stay with justInt. It’s probably large enough for your needs. Here’s what you need to know aboutInt:
Inton 32-bit platforms isInt32.
Inton 64-bit platforms isInt64.
That is, when you declare a variable asInt, Swift will do the work of changing that toInt32orInt64. You don’t need to do anything on your end.
Intcan be both positive and negative in value.
Intwill be the defaulttypewhen you declare a variable with a number and no decimals:
var someInt = 3 // this will be an Int
UIntis provided as anunsignedinteger. An unsigned number must be positive, whereas asignednumber (anInt) can be negative. For consistency, Apple recommends that you generally useInteven when you know that a value will never be negative.
Doubledenotes 64-bit floating-point numbers.Doublehas a higher precision thanfloat, with at least 15 decimal digits.Doublewill be the chosen type when you declare a variable that has decimals in it:
var someDouble = 3.14 // this will be a double
Combining any integer with any floating-point number results in aDouble:
3 + 3.14 // 6.14 works and will be a double var three = 3 var threePointOne = 3.1 three + threePointOne //Error because you can't mix types
- Floatdenotes 32-bit floating-point numbers.Floatcan have a precision as small as 6. Whether you chooseFloatorDoubleis completely up to you and your situation. Swift will chooseDoublewhen no type is declared.
Along withDecimalnumbers, you can useBinary,Octal, andHexadecimalnumbers:
- Decimalis the default for all numbers, so no prefix is needed.
- Create aBinarynumber by adding a0bprefix.
- Octaluses a0oprefix.
- Hexadecimaluses a0xprefix.
You can check the type of the object by using theiskeyword. Theiskeyword will return a Boolean. In this example we use theAnyclass to denote thatpican be anything at all until we type it as aFloat:
var pi:Any? pi = 3.141 pi is Double //true pi is Float //false
Notice that you declare this type asAny?in the preceding example. The question mark denotes an optional, which allows us to not set an initial value without causing an error. TheAnytype can be any type (exactly what it says). Objective-C is not as strict as Swift, and you need to be able to intermingle the two languages. For this purpose,AnyandAnyObjectwere created, which allows you to put any type in an object. Think about arrays in Objective-C, which can mix different types together; for that purpose you need to give Swift the ability to have arrays of different types. You’ll learn more about this later in the chapter.
Swift is the only programming language (that I know of) that lets you put underscores in numbers to make them more legible. Xcode ignores the underscores when it evaluates your code. You might find using underscores especially useful with big numbers when you want to denote a thousand-comma separator, as in this case:
var twoMil = 2_000_000
Before you can add two numbers together, they must be made into the same type. For example, the following will not work:
var someNumA:UInt8 = 8 var someNumB:Int8 = 9 someNumA + someNumB //Int8 is not convertible to UInt8
The reason this does not work is thatsomeNumAis aUInt8andsomeNumBis anInt8. Swift is very strict about the combination of things.
To make this work, you must convert one of the types so that the two types are the same. To do this, use theinitializerof the type. For example, you can use the initializerUInt8, which can convertsomeNumBto aUInt8for you:
someNumA + UInt8(someNumB)
Swift is strict and makes sure that you convert types before you can combine them.
We had to do a lot of conversions of types in a previous example.