Integers

Swift provides signed and unsigned integers in 8, 16, 32, and 64 bit forms. An 8-bit unsigned integer is of type UInt8.

let minValue = UInt8.min  // minValue is equal to 0, and is of type UInt8
let maxValue = UInt8.max  // maxValue is equal to 255, and is of type UInt8

Swift provides integer type, Int, which has the same size as the current platform’s native word size

On a 32-bit platform, Int is the same size as Int32.

On a 64-bit platform, Int is the same size as Int64.

On a 32-bit platform, UInt is the same size as UInt32.

On a 64-bit platform, UInt is the same size as UInt64.

Floating-Point Numbers

  • Double represents a 64-bit floating-point number.
  • Float represents a 32-bit floating-point number.

Type Safety and Type Inference

swift는 Type Safe 언어이다. 즉 Int로 정해진 변수에 Double타입의 데이터를 대입할수 없다. 그렇다고 모든 상수,변수의 data type을 정해줘야하는 것은 아니다. 처음 대입하는 데이터를 가지고 swift는 알맞은 data type을 정한다. 이를 type inference라고 한다.

Swift always chooses Double (rather than Float) when inferring the type of floating-point numbers.

Numeric Literals

let decimalInteger = 17
let binaryInteger = 0b10001       // 17 in binary notation
let octalInteger = 0o21           // 17 in octal notation
let hexadecimalInteger = 0x11     // 17 in hexadecimal notation

  • 1.25e2 means 1.25 x 102, or 125.0.
  • 1.25e-2 means 1.25 x 10-2, or 0.0125.

let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1

Numeric Type Conversion

let cannotBeNegative: UInt8 = -1
// UInt8 cannot store negative numbers, and so this will report an error

let tooBig: Int8 = Int8.max + 1
// Int8 cannot store a number larger than its maximum value,
// and so this will also report an error

let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
let twoThousandAndOne = twoThousand + UInt16(one)

let three = 3
let pointOneFourOneFiveNine = 0.14159
let pi = Double(three) + pointOneFourOneFiveNine
// pi equals 3.14159, and is inferred to be of type Double

NOTE

The rules for combining numeric constants and variables are different from the rules for numeric literals. The literal value 3 can be added directly to the literal value 0.14159, because number literals don’t have an explicit type in and of themselves. Their type is inferred only at the point that they’re evaluated by the compiler. 그냥 literal 끼리 변수,상수에 할당하기 전에 연산하는 것은 가능하다는 이야기 이다. 

Type Aliases

typealias AudioSample = UInt16

Once you define a type alias, you can use the alias anywhere you might use the original name:

var maxAmplitudeFound = AudioSample.min
// maxAmplitudeFound is now 0

Booleans

let orangesAreOrange = true
let turnipsAreDelicious = false

let i = 1
if i {
  // this example will not compile, and will report an error, 일반 다른타입의 데이터는 Bool

}

Tuples

The values within a tuple can be of any type and don’t have to be of the same type as each other.

let http404Error = (404, “Not Found”)
let (statusCode, statusMessage) = http404Error

print(“The status code is (statusCode)”)
// Prints “The status code is 404”

print(“The status message is (statusMessage)”)
// Prints “The status message is Not Found”

If you only need some of the tuple’s values, ignore parts of the tuple with an underscore (_) when you decompose the tuple:

let (justTheStatusCode, _) = http404Error

print(“The status code is (justTheStatusCode)”)
// Prints “The status code is 404”

Alternatively, access the individual element values in a tuple using index numbers starting at zero:

print(“The status code is (http404Error.0)”)
// Prints “The status code is 404”

print(“The status message is (http404Error.1)”)
// Prints “The status message is Not Found”

You can name the individual elements in a tuple when the tuple is defined:

let http200Status = (statusCode: 200, description: “OK”)

If you name the elements in a tuple, you can use the element names to access the values of those elements:

print(“The status code is (http200Status.statusCode)”)
// Prints “The status code is 200”

print(“The status message is (http200Status.description)”)
// Prints “The status message is OK”

Optionals

You use optionals in situations where a value may be absent.

let possibleNumber = “123”
let convertedNumber = Int(possibleNumber)
// convertedNumber is inferred to be of type “Int?”, or “optional Int”

위에서 possibleNumber가 다른 일반 string의 경우에는 Int전환이 불가능하다. 그런 경우는 convertedNumber 에 nil 이 저장될수 있으므로 convertedNumber 는 Int?로 자동 설정되는 것이다.

var serverResponseCode: Int? = 404
// serverResponseCode contains an actual Int value of 404

serverResponseCode = nil
// serverResponseCode now contains no value

NOTE

You can’t use nil with nonoptional constants and variables. If a constant or variable in your code needs to work with the absence of a value under certain conditions, always declare it as an optional value of the appropriate type.

If you define an optional variable without providing a default value, the variable is automatically set to nil for you:

var surveyAnswer: String?
// surveyAnswer is automatically set to nil

If Statements and Forced Unwrapping

You can use an if statement to find out whether an optional contains a value by comparing the optional against nil. You perform this comparison with the “equal to” operator (==) or the “not equal to” operator (!=).

Once you’re sure that the optional does contain a value, you can access its underlying value by adding an exclamation mark (!) to the end of the optional’s name. 

if convertedNumber != nil {
   print(“convertedNumber has an integer value of (convertedNumber!).”)
}
// Prints “convertedNumber has an integer value of 123.”

NOTE

Trying to use ! to access a nonexistent optional value triggers a runtime error. Always make sure that an optional contains a non-nil value before using ! to force-unwrap its value.

Optional Binding

You use optional binding to find out whether an optional contains a value, and if so, to make that value available as a temporary constant or variable.

if let actualNumber = Int(possibleNumber) {
   print(“”(possibleNumber)” has an integer value of (actualNumber)”)
} else {
   print(“”(possibleNumber)” could not be converted to an integer”)
}
// Prints “"123” has an integer value of 123"

You can include as many optional bindings and Boolean conditions in a single if statement as you need to, separated by commas. If any of the values in the optional bindings are nil or any Boolean condition evaluates to false, the whole if statement’s condition is considered to be false. (여러개의 optional binding을 하나의 if 구문에서 사용하는 것은 여러개의 조건문이 and로 연결된것으로 본다)

if let firstNumber = Int(“4”), let secondNumber = Int(“42”), firstNumber < secondNumber && secondNumber < 100 {
   print(“(firstNumber) < (secondNumber) < 100”)
}
// Prints “4 < 42 < 100”

implicitly Unwrapped Optionals

it’s clear from a program’s structure that an optional will always have a value, after that value is first set. In these cases, it’s useful to remove the need to check and unwrap the optional’s value every time it’s accessed.

You write an implicitly unwrapped optional by placing an exclamation mark (String!) rather than a question mark (String?) after the type.

let possibleString: String? = “An optional string.”
let forcedString: String = possibleString! // requires an exclamation mark

let assumedString: String! = “An implicitly unwrapped optional string.”
let implicitString: String = assumedString // no need for an exclamation mark

You can still treat an implicitly unwrapped optional like a normal optional, to check if it contains a value:

if assumedString != nil {
   print(assumedString)
}
// Prints “An implicitly unwrapped optional string.”

You can also use an implicitly unwrapped optional with optional binding, to check and unwrap its value in a single statement:

if let definiteString = assumedString {
   print(definiteString)
}
// Prints “An implicitly unwrapped optional string.”

NOTE

Don’t use an implicitly unwrapped optional when there’s 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.

Error Handling

When a function encounters an error condition, it throws an error. That function’s caller can then catch the error and respond appropriately.

func canThrowAnError() throws {
   // this function may or may not throw an error
}

A function indicates that it can throw an error by including the throws keyword in its declaration. When you call a function that can throw an error, you prepend the try keyword to the expression.

Swift automatically propagates errors out of their current scope until they’re handled by a catch clause.

do {
   try canThrowAnError()
   // no error was thrown
} catch {
   // an error was thrown
}

A do statement creates a new containing scope, which allows errors to be propagated to one or more catchclauses.

Here’s an example of how error handling can be used to respond to different error conditions:

func makeASandwich() throws {
   // …
}

do {
   try makeASandwich()
   eatASandwich()
} catch SandwichError.outOfCleanDishes {
   washDishes()
} catch SandwichError.missingIngredients(let ingredients) {
   buyGroceries(ingredients)

}

Assertions and Preconditions

You use them to make sure an essential condition is satisfied before executing any further code. If the Boolean condition in the assertion or precondition evaluates to true, code execution continues as usual. If the condition evaluates to false, the current state of the program is invalid; code execution ends, and your app is terminated.

error handling과는 달리 assertions and preconditions aren’t used for recoverable or expected errors. (통과하지 못하면 프로그램 정지)

The difference between assertions and preconditions is in when they’re checked: Assertions are checked only in debug builds, but preconditions are checked in both debug and production builds.

Debugging with Assertions

let age = -3
assert(age >= 0, “A person’s age can’t be less than zero.”)
// This assertion fails because -3 is not >= 0.

You can omit the assertion message

assert(age >= 0)

If the code already checks the condition, you use the assertionFailure(_:file:line:) function to indicate that an assertion has failed. For example:

if age > 10 {
   print(“You can ride the roller-coaster or the ferris wheel.”)
} else if age > 0 {
   print(“You can ride the ferris wheel.”)
} else {
   assertionFailure(“A person’s age can’t be less than zero.”)
}

Enforcing Preconditions

// In the implementation of a subscript…
precondition(index > 0, “Index must be greater than zero.”)

Comments are closed.

Post Navigation