By Jordan Morgan, translator: Zheng Yiyi; Proofreading: NUMbbbbb, PMST; Finalized: Pancf
I’ve said something before and I want to say it again today. That is to forge iron also need their own hard. Strict requirements for our own abilities can help us achieve all the things we dream of.
It may sound negative, but knowledge is never finished. In any case, today we’ll take a look at each of the keywords in Swift (V3.0.1), and we’ll introduce each keyword along with a code that explains it.
Among these keywords, there may be parts that you are familiar with or unfamiliar with. But for the best reading and learning experience, I’ve listed them all. This article is a bit long. Are you ready?
Let’s get started now.
Declarative keywords
Associatedtype: In the protocol, defines the placeholder name for a type. The placeholder is not specified as a specific type until the protocol is implemented.
protocol Entertainment { associatedtype MediaType } class Foo : Entertainment {typeAlias MediaType = String // Can specify any type}Copy the code
Class: A general-purpose, flexible structure that is an essential part of a program. Similar to structs, except that:
-
Allows a class to inherit features from another class.
-
Type conversion, which allows checking and specifying the actual type of a class at run time.
-
The destructor method allows an instance of a class to release all resources.
-
Reference counting allows multiple references to point to an instance.
class Person
{
var name:String
var age:Int
var gender:String
}
Deinit: This method is called when an instance of a class is about to be destroyed.
Class Person {var name:String var age:Int var gender:String deinit {// Free resources from the heap}}Copy the code
Enum: Defines a type that contains an associated set of values and can be used in a type-safe manner. In Swift, enumerations are first-class types, with features that only class supports in other languages.
enum Gender
{
case male
case female
}
Copy the code
Extension: Allows you to add new functionality to existing classes, structs, enumerations, and protocol types.
class Person
{
var name:String = ""
var age:Int = 0
var gender:String = ""
}
extension Person
{
func printInfo()
{
print("My name is \(name), I'm \(age) years old and I'm a \(gender).")
}
}
Copy the code
Fileprivate: indicates the access control permission, which is allowed to be accessed only in defined source files.
Class Person {fileprivate var jobTitle:String = ""} extension Person {// If extension and class are in the same file, PrintJobTitle () {print("My job is (jobTitle)")}}Copy the code
Func: Contains blocks of code used to perform specific tasks.
func addNumbers(num1:Int, num2:Int) -> Int
{
return num1+num2
}
Copy the code
Import: Introduces a framework or application built as a standalone unit.
Import UIKit // You can use all the code in UIKit framework class Foo {}Copy the code
Init: Preparation for initialization of instances of classes, structs, and enumerations.
Class Person {init() {// Set default, instance ready to be used}}Copy the code
Inout: Passes a value to a function that can be modified by the function and then passes the value back to the caller to replace the initial value. Applies to reference types and value types.
func dangerousOp(_ error:inout NSError?) { error = NSError(domain: "", code: 0, userInfo: ["":""]) } var potentialError:NSError? DangerousOp (&potentialError) // The code runs here and potentialError is no longer nil, but has already been initializedCopy the code
Internal: indicates the access control permission. All source files in the same module can be accessed. If they are in different modules, the access is not allowed.
class Person
{
internal var jobTitle:String = ""
}
let aPerson = Person()
aPerson.jobTitle = "This can set anywhere in the application"
Copy the code
Let: Define an immutable variable.
let constantString = "This cannot be mutated going forward"
Copy the code
Open: Access control permission that allows all classes in the source file to be accessed and subclassed outside the defined module. For class members, access and overwriting are allowed outside of the defined module.
open var foo:String? // This property can be overridden and accessed inside or outside the app. This access modifier is applied when developing the framework.Copy the code
Operator: special symbol used to check, modify, and combine values.
// unary operator "-", Change value symbol let foo = 5 let anotherFoo = -foo //anotherFoo = -5 // Binary operator "+" adds two values let box = 5 + 3 // logical operator "&&" combines two Boolean values If didPassCheckOne && didPassCheckTwo / / the ternary operator need to use the three values let isLegalDrinkingAgeInUS: Bool = age > = 21? true : falseCopy the code
Private: Access control permission that allows entities to access only defined classes and extensions within the same source file.
Class Person {private var jobTitle:String = ""} PrintJobTitle () {print("My job is (jobTitle)")}}Copy the code
Protocol: Defines a set of methods, properties, or other requirements that satisfy a particular task and set of functions.
protocol Blog { var wordCount:Int { get set } func printReaderStats() } class TTIDGPost : Blog {var wordCount:Int init(wordCount:Int) {self.wordCount = wordCount} func printReaderStats() {Copy the code
Public: Access control permission that allows all classes in the source file to be accessed outside the defined module, but can be subclassed only within the same module. For class members, access and overwriting are allowed under the same module.
public var foo:String? // Can only be overridden and accessed within the app.Copy the code
Static: Used to define class methods that are called on the type itself. You can also define static members.
class Person
{
var jobTitle:String?
static func assignRandomName(_ aPerson:Person)
{
aPerson.jobTitle = "Some random job"
}
}
let somePerson = Person()
Person.assignRandomName(somePerson)
//somePerson.jobTitle 的值是 "Some random job"
Copy the code
Struct: Generic, flexible structure that is the foundation of a program and provides a default initialization method. Unlike a class, when a struct is passed in code, it is copied and reference counting is not used. In addition, structs do not have the following functions:
-
Use inheritance.
-
Type conversion at run time.
-
Use the destructor method.
struct Person
{
var name:String
var age:Int
var gender:String
}
Subscript: A shortcut to accessing member elements in a collection, list, or sequence.
Var postMetrics = ["Likes":422, "percentage ":0.58, "Views":3409] let postMetrics = postMetrics["Likes"]Copy the code
Typealias: Alias a class that already exists in the code.
typealias JSONDictionary = [String: AnyObject]
func parseJSON(_ deserializedData:JSONDictionary){}
Copy the code
Var: Defines variable variables.
var mutableString = ""
mutableString = "Mutated"
Copy the code
Keywords in statements
Break: Terminates the execution of a loop in a program, such as an if statement or switch statement.
for idx in 0...3
{
if idx % 2 == 0
{
//当 idx 等于偶数时,退出 for 循环
break
}
}
Copy the code
Case: This statement is listed in the switch statement, and pattern matching can be performed at each branch.
let box = 1
switch box
{
case 0:
print("Box equals 0")
case 1:
print("Box equals 1")
default:
print("Box doesn't equal 0 or 1")
}
Copy the code
Continue: Used to terminate the current iteration of the loop and proceed to the next iteration without stopping the execution of the entire loop.
for idx in 0... Continue} print("This code never fires on even numbers")}Copy the code
Default: Used to cover all unlisted enumerators in the switch statement.
let box = 1
switch box
{
case 0:
print("Box equals 0")
case 1:
print("Box equals 1")
default:
print("Covers any scenario that doesn't get addressed above.")
}
Copy the code
Defer: To execute a piece of code before the program leaves the current scope.
Func cleanUpIO() {defer {print("This is called right before no scope")} // Close the file stream, etc. }Copy the code
Do: Used to indicate the beginning of a section of code that handles errors.
Do {try expression // statement} catch someError ex {// handle error}Copy the code
Else: Used with the if statement. When the condition is true, execute a piece of code. When the condition is false, execute another piece of code.
if val > 1
{
print("val is greater than 1")
}
else
{
print("val is not greater than 1")
}
Copy the code
Fallthrough: Explicitly allows code execution to continue from the current case to the next adjacent case.
let box = 1
switch box
{
case 0:
print("Box equals 0")
fallthrough
case 1:
print("Box equals 0 or 1")
default:
print("Box doesn't equal 0 or 1")
}
Copy the code
For: Iterates over a sequence, such as a set of numbers in a specific range, elements in an array, characters in a string. * paired with the in keyword.
for _ in 0.. <3 { print ("This prints 3 times") }Copy the code
Guard: Leaves current scope when more than one condition is not satisfied. It also provides the ability to unpack optional types.
private func printRecordFromLastName(userLastName: String?) { guard let name = userLastName, name ! Print (datastore.findBylastName (name))} else {//userLastName = "Null";Copy the code
If: Executes the code when the condition is met.
if 1 > 2
{
print("This will never execute")
}
Copy the code
In: Iterates over a sequence, such as a set of numbers in a specific range, elements in an array, characters in a string. * This parameter is used with key.
for _ in 0.. <3 { print ("This prints 3 times") }Copy the code
Repeat: Executes the code in the loop once before using the loop’s criteria.
repeat
{
print("Always executes at least once before the condition is considered")
}
while 1 > 2
Copy the code
Return: Immediately terminates the current context, leaving the current scope, and can return with an additional value.
Func doNothing() {return let anInt = 0 print("This never prints (anInt)")}Copy the code
and
func returnName() -> String? {return self.userName // leave and return the value of userName}Copy the code
Switch: Compares the given value to the branch. Execute the branch code for the first successful pattern match.
let box = 1
switch box
{
case 0:
print("Box equals 0")
fallthrough
case 1:
print("Box equals 0 or 1")
default:
print("Box doesn't equal 0 or 1")
}
Copy the code
Where: Requires that the association type must adhere to a specific protocol, or that the type parameters and the association type must be consistent. It can also be used to provide additional conditions in cases that satisfy control expressions.
Where clauses can be used in a variety of scenarios. The following example illustrates the main application scenario for WHERE, pattern matching in generics.
protocol Nameable { var name:String {get set} } func createdFormattedName(_ namedEntity:T) -> String where T:Equatable { Return "This thing name is "+ namedentity. name};Copy the code
and
For I in 0... 3 where I % 2 == 0 {print(I) // print 0 and 2}Copy the code
While: A loop executes a specific statement until the condition is not met, then stops the loop.
while foo ! = bar { print("Keeps going until the foo == bar") }Copy the code
Keywords in expressions and types
Any: Used to represent instances of Any type, including function types.
var anything = [Any]()
anything.append("Any Swift type can be added")
anything.append(0)
anything.append({(foo: String) -> String in "Passed in (foo)"})
Copy the code
As: Type conversion operator used to try to convert a value to another type.
var anything = [Any]()
anything.append("Any Swift type can be added")
anything.append(0)
anything.append({(foo: String) -> String in "Passed in (foo)" })
let intInstance = anything[1] as? Int
Copy the code
or
var anything = [Any]()
anything.append("Any Swift type can be added")
anything.append(0)
anything.append({(foo: String) -> String in "Passed in (foo)" })
for thing in anything
{
switch thing
{
case 0 as Int:
print("It's zero and an Int type")
case let someInt as Int:
print("It's an Int that's not zero but (someInt)")
default:
print("Who knows what it is")
}
}
Copy the code
Catch: If an error is thrown in a DO, the catch tries to match and decides how to handle the error. * Excerpts from a blog POST I wrote about Swift’s error handling.
do
{
try haveAWeekend(4)
}
catch WeekendError.Overtime(let hoursWorked)
{
print("You worked (hoursWorked) more than you should have")
}
catch WeekendError.WorkAllWeekend
{
print("You worked 48 hours :-0")
}
catch
{
print("Gulping the weekend exception")
}
Copy the code
False: Swift one of two constant values used to represent booleans, the opposite of true.
Let alwaysFalse = false let alwaysTrue = true if alwaysFalse {print("Won't print, alwaysFalse is false 😉")}Copy the code
Is: Type checking operator used to determine whether an instance is of a subclass type.
class Person {}
class Programmer : Person {}
class Nurse : Person {}
let people = [Programmer(), Nurse()]
for aPerson in people
{
if aPerson is Programmer
{
print("This person is a dev")
}
else if aPerson is Nurse
{
print("This person is a nurse")
}
}
Copy the code
Nil: Represents a stateless value of any type in Swift.
Unlike nil in Objective-C, nil represents a pointer to a nonexistent object.
Class Person{} struct Place{} // Any Swift type or instance can be nil var statelessPerson:Person? = nil var statelessPlace:Place? = nil var statelessInt:Int? = nil var statelessString:String? = nilCopy the code
Rethrows: Specifies that the current function throws an error only if an argument throws an error.
func networkCall(onComplete:() throws -> Void) rethrows
{
do
{
try onComplete()
}
catch
{
throw SomeError.error
}
}
Copy the code
Super: In subclasses, expose the methods, attributes, and subscripts of the parent class.
class Person { func printName() { print("Printing a name. ") } } class Programmer : Person { override func printName() { super.printName() print("Hello World!" }} let aDev = Programmer() adev.printName () // Print a name. Hello World!Copy the code
Self: An implicit attribute that an instance of any type has, equivalent to the instance itself. It can also be used to distinguish between function parameters and member attribute names.
class Person { func printSelf() { print("This is me: (self)")}} let aPerson = Person() aPerson. PrintSelf ()Copy the code
Self: in the protocol, indicates the entity type that complies with the current protocol.
protocol Printable { func printTypeTwice(otherMe:Self) } struct Foo : Printable { func printTypeTwice(otherMe: Foo) { print("I am me plus (otherMe)") } } let aFoo = Foo() let anotherFoo = Foo() aFoo.printTypeTwice(otherMe: // Print I am me plus Foo()Copy the code
Throw: Used to explicitly throw an error in the current context.
enum WeekendError: Error
{
case Overtime
case WorkAllWeekend
}
func workOvertime () throws
{
throw WeekendError.Overtime
}
Copy the code
Throws: Indicates that an error may be thrown in a function, method, or initialization method.
enum WeekendError: Error { case Overtime case WorkAllWeekend } func workOvertime () throws { throw WeekendError.Overtime } //"throws" It says that when you call a method, you need to use try, try? , try! try workOvertime()Copy the code
True: Swift Either of two constant values used to represent booleans, represented as true.
let alwaysFalse = false
let alwaysTrue = true
if alwaysTrue { print("Always prints")}
Copy the code
Try: indicates that subsequent calls to the function may raise an error. There are three different ways to use it: try, try? , try! .
Let aResult = try dangerousFunction() // Handle error, or continue with error let aResult = try! DangerousFunction () // If let aResult = try? DangerousFunction () // Unpack Optional type.Copy the code
Keywords in the schema
_ : a wildcard used to match or omit any value.
for _ in 0.. <3 { print("Just loop 3 times, index has no meaning") }Copy the code
Another use:
Let _ = Singleton() // Ignore unused variablesCopy the code
Keywords that begin with #
#available: Check the availability of the API at run time, based on platform parameters, through conditions of if, while, guard statements.
if #available(iOS 10, *)
{
print("iOS 10 APIs are available")
}
Copy the code
#colorLiteral: A literal expression used in the playground to create a color picker that is selected and assigned to the variable.
Let aColor = #colorLiteral // create color pickerCopy the code
#column: A special literal expression used to get the starting column number of the literal representation.
class Person
{
func printInfo()
{
print("Some person info - on column (#column)")
}
}
let aPerson = Person()
aPerson.printInfo() //Some person info - on column 53
Copy the code
#else: Conditional compilation control statement, used to control programs to execute different code under different conditions. Used in conjunction with the #if statement. When the condition is true, the code is executed. When the condition is false, execute another piece of code.
#if os(iOS)
print("Compiled for an iOS device")
#else
print("Not on an iOS device")
#endif
Copy the code
#elseif: Conditional compilation control statement used to control the program to execute code under different conditions. Used in conjunction with the #if statement. When the condition is true, the code is executed.
#if os(iOS)
print("Compiled for an iOS device")
#elseif os(macOS)
print("Compiled on a mac computer")
#endif
Copy the code
#endif: Conditional compilation control statement, used to control the program to execute code under different conditions. Used to indicate the end of conditionally compiled code.
#if os(iOS)
print("Compiled for an iOS device")
#endif
Copy the code
#file: Special literal expression that returns the name of the source file in which the current code resides.
class Person { func printInfo() { print("Some person info - inside file (#file)") } } let aPerson = Person() APerson. PrintInfo () //Some person info - inside file /* Playground file path */Copy the code
#fileReference: playground literal syntax for creating a file picker that picks and returns an instance of NSURL.
Let fontFilePath = #fileReference create file pickerCopy the code
#function: a special literal expression that returns the function name. In a method, return the method name. In the getter or setter for the property, return the property name. In special members, such as init or subscript, the keyword name is returned. At the top level of the file, returns the current module name.
class Person
{
func printInfo()
{
print("Some person info - inside function (#function)")
}
}
let aPerson = Person()
aPerson.printInfo() //Some person info - inside function printInfo()
Copy the code
#if: Conditional compilation control statement, used to control the program to compile code under different conditions. Determine whether to execute code by judging conditions.
#if os(iOS)
print("Compiled for an iOS device")
#endif
Copy the code
#imageLiteral: playground literal syntax, create image picker, select and return UIImage instance.
Let anImage = #imageLiteral // Select images from playgroundCopy the code
#line: Special literal expression to get the number of lines of current code.
class Person
{
func printInfo()
{
print("Some person info - on line number (#line)")
}
}
let aPerson = Person()
aPerson.printInfo() //Some person info - on line number 5
Copy the code
#selector: An expression used to create an Objective-C selector that statically checks for the existence of the method and exposes it to Objective-C.
Control. sendAction(#selector(doAnObjCMethod), to: target, forEvent: event)Copy the code
#sourceLocation: line control statement that specifies a completely different number of lines and source file names. It is used for Swift diagnosis and debugging.
#sourceLocation(file:"foo.swift", #sourceLocation() print(#file) print(#line) print(#line)Copy the code
Keywords in a particular context
These keywords, when outside the corresponding context, can be used as identifiers.
Associativity: Indicates the order in which the operator of the same precedence should be combined in the absence of braces. Use left, right, and None.
infix operator ~ { associativity right precedence 140 }
4 ~ 8
Copy the code
Convenience: a second-rate convenience constructor that finally invokes the specified constructor to initialize the instance.
class Person { var name:String init(_ name:String) { self.name = name } convenience init() { self.init("No Name") } } Let me = Person() print(me.name)// print "No name"Copy the code
Dynamic: Indicates that the compiler does not inline or virtualize methods on class members or functions. This means that access to this member is distributed dynamically using the Objective-C runtime (instead of static calls).
Class Person {// implicitly indicate "objc" attributes // this is useful for libraries or frameworks that rely on the dark magic of objC-C, such as KVO, KVC, Swizzling. }Copy the code
DidSet: Property observer, called as soon as the value is stored in the property.
Var data = [1,2,3] {didSet {tableview.reloaddata ()}}Copy the code
Final: Prevents methods, attributes, and subscripts from being overwritten.
Final class Person {} class Programmer: Person {} // compile errorCopy the code
Get: Returns the value of the member. It can also be used for computational attributes to get the value of other attributes indirectly.
class Person { var name:String { get { return self.name } set { self.name = newValue} } var indirectSetName:String { get {if let aFullTitle = self.fullTitle {return aFullTitle} return ""} set (newTitle) { NewValue self.fulltitle = "(self.name) :(newTitle)"}}}Copy the code
Infix: Specifies an operator to use between two values. If a brand new global operator is defined as infix, you also need to specify the priority.
let twoIntsAdded = 2 + 3
Copy the code
Indirect: Indicates that in an enumeration type, a member has an instance of the same enumeration type as an associated value.
indirect enum Entertainment
{
case eventType(String)
case oneEvent(Entertainment)
case twoEvents(Entertainment, Entertainment)
}
let dinner = Entertainment.eventType("Dinner")
let movie = Entertainment.eventType("Movie")
let dateNight = Entertainment.twoEvents(dinner, movie)
Copy the code
Lazy: Indicates the initial value of the property until it is first used.
Class Person {lazy var personalityTraits = {// Expensive database overhead return ["Nice", "Be hilarious"]} ()} let aPerson = Person () aPerson. PersonalityTraits / / when personalityTraits is accessed for the first time, the database to begin to workCopy the code
Left: indicates that the associativity of the operator is left to right. When braces are not used, it can be used to correctly determine the order of execution of the same precedence operators.
// The associativity of the "-" operator is 10-2-4 from left to rightCopy the code
Mutating: Allows you to modify the property values of a structure or an enumeration instance in a method.
struct Person
{
var job = ""
mutating func assignJob(newJob:String)
{
self = Person(job: newJob)
}
}
var aPerson = Person()
aPerson.job //""
aPerson.assignJob(newJob: "iOS Engineer at Buffer")
aPerson.job //iOS Engineer at Buffer
Copy the code
None: Is an unassociative operator. Such operators are not allowed to appear next to each other.
//"<" is the non-associative operator 1 < 2 < 3 // failed to compileCopy the code
Nonmutating: SETTER methods that specify members do not modify the value of the instance, but may have other consequences.
enum Paygrade { case Junior, Middle, Senior, Master var experiencePay:String? { get { database.payForGrade(String(describing:self)) } nonmutating set { if let newPay = newValue { database.editPayForGrade(String(describing:self), NewSalary :newPay)}}}} let currentPay = Paygrade.Middle Currentpay. experiencePay = "$45,000"Copy the code
Optional: Specifies optional methods in the protocol. Entity classes that comply with this protocol may not implement this method.
@objc protocol Foo
{
func requiredFunction()
@objc optional func optionalFunction()
}
class Person : Foo
{
func requiredFunction()
{
print("Conformance is now valid")
}
}
Copy the code
Override: Specifies that subclasses provide custom implementations that override instance methods, type methods, instance attributes, type attributes, and subscripts of the parent class. If not, it inherits directly from the parent class.
class Person { func printInfo() { print("I'm just a person!" ) } } class Programmer : Person { override func printInfo() { print("I'm a person who is a dev!" }} let aPerson = Person() let aDev = Programmer() aPerson. PrintInfo () Adev.printinfo () // Prints I'm a person who is a dev!Copy the code
Postfix: Operator that follows a value.
var optionalStr:String? = "Optional"
print(optionalStr!)
Copy the code
Precedence: specifies that the precedence of an operator is higher than that of another operator.
infix operator ~ { associativity right precedence 140 }
4 ~ 8
Copy the code
Prefix: Operator that precedes the value.
Var anInt = 2 anInt = -anint //anInt = -2Copy the code
Required: Ensures that the compiler checks all subclasses of the class that all implement the specified constructor methods.
class Person { var name:String? required init(_ name:String) { self.name = name } } class Programmer : Person {// If this method is not implemented, compilation will not pass required init(_ name: String) {super.init(name)}}Copy the code
Right: indicates that the associativity of the operator is from right to left. Can be used to correctly determine the order of the same precedence operators when braces are not used.
/ / "??" Operator associativity is from right to left var box:Int? var sol:Int? = 2 let foo:Int = box ?? sol ?? 0 //Foo is equal to 2Copy the code
Set: Sets the value of a member by getting the new value. You can also use computational properties to set other properties indirectly. If the setter for a computational property does not define the name of the newValue, the default newValue can be used.
class Person { var name:String { get { return self.name } set { self.name = newValue} } var indirectSetName:String { get {if let aFullTitle = self.fullTitle {return aFullTitle} return ""} set (newTitle) { NewValue self.fulltitle = "(self.name) :(newTitle)"}}}Copy the code
Type: indicates any Type, including class Type, structure Type, enumeration Type, and protocol Type.
class Person {}
class Programmer : Person {}
let aDev:Programmer.Type = Programmer.self
Copy the code
unowned: Let instance A in the circular reference not forcibly reference instance B. The premise is that instance B has A longer lifetime than instance A.
class Person { var occupation:Job? } // When the Person instance does not exist, the job does not exist. The life cycle of a job depends on the Person holding it. class Job { unowned let employee:Person init(with employee:Person) { self.employee = employee } }Copy the code
Weak: Allows instance A in A circular reference to weakly reference instance B, but not strongly reference it. Instance B has a shorter lifetime and is released first.
class Person { var residence:House? } class House { weak var occupant:Person? } var me:Person? = Person() var myHome:House? = House() me! .residence = myHome myHome! .occupant = me me = nil myHome! . Occupant // myHome = nilCopy the code
WillSet: Property observer, called before the value is stored in the property.
class Person { var name:String? { willSet(newValue) {print("I've got a new name, it's (newValue)!" }} let aPerson = Person() aPerson. Name = "Jordan" // Before assigning, print "I've got a new name, it's Jordan!Copy the code
conclusion
B: wow!
This is really an interesting creation. I’ve learned so many things I never thought I’d learn before I wrote. But I think the trick here is not to memorize it, but to think of it as a list of definitions that you can use for quizzes.
Instead, I suggest you keep this list handy and review it from time to time. If you can do this, the next time you need to use a particular keyword in a different situation, you’ll almost certainly be able to recall it and use it.
See you next time.
This article is translated by SwiftGG translation team and has been authorized to be translated by the authors. Please visit swift.gg for the latest articles.