Swift教程(一)

前端之家收集整理的这篇文章主要介绍了Swift教程(一)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

基础部分

常量和变量

声明常量和变量

常量和变量必须在使用前声明,用let声明常量,用var声明变量。

let@H_301_15@ a = 10@H_301_15@
var@H_301_15@ b = 0@H_301_15@

类型标注

var@H_301_15@ message@H_301_15@: String@H_301_15@

常量和变量的命名

let@H_301_15@ π = 3.141592654@H_301_15@
let@H_301_15@ 你好 = "你好,世界。"@H_301_15@
let@H_301_15@ ☏ = "110"@H_301_15@

下面的例子中,friendlyWelcomeHello!变为Hi

var@H_301_15@ friendlyWelcome = "Hello!"@H_301_15@
friendlyWelcome = "Hi"@H_301_15@

但是下面这段代码,在编译时会报错。

let@H_301_15@ languageName = "swift"@H_301_15@
languageName = "Objective-C"@H_301_15@
// 因为languageName是常量,其值不可改变。@H_301_15@

输出常量和变量

println(friendlyWelcome)@H_301_15@
// 输出“Hi”@H_301_15@

println("this is a string"@H_301_15@)@H_301_15@
// 输出“this is a string”@H_301_15@

下面这段代码会告诉你字符串插值怎么使用。

println("The current value of@H_301_15@ friendlyWelcome is@H_301_15@ \(friendlyWelcome)")
// 输出“The current value of@H_301_15@ friendlyWelcome is@H_301_15@ Hi”

注释

//这是一个单行注释@H_301_15@

/* 这是一个 多行注释。 */@H_301_15@

分号

如果你打算在同一行写多条独立的语句,那么分号是必须的,否则,分号不是必须的。

整数

整数范围

let@H_301_15@ maxValue =@H_301_15@ UInt8.@H_301_15@max@H_301_15@  // 255@H_301_15@
let@H_301_15@ minValue =@H_301_15@ UInt8.@H_301_15@min@H_301_15@  // 0@H_301_15@

Int

在32位平台上,IntInt32长度相同。
在64位平台上,IntInt64长度相同。

UInt

一般情况下不推荐使用UInt。

浮点数

Double表示64位浮点数,当你需要存储很大或者很高精度的浮点数时请使用此类型。
Float表示32位浮点数。精度要求不高的话可以使用此类型。

类型安全和类型推断

Swift是类型安全的,它在编译时进行类型检查,把不匹配的类型标记错误,可以让你再开发的时候尽早发现并修复错误

let@H_301_15@ meaningOfLife = 42@H_301_15@
// meaningOfLife会被推测为Int类型@H_301_15@

如果你没有给浮点字面量标明类型,Swift会推断你想要的是Double:

let@H_301_15@ pi = 3.14159@H_301_15@
// pi会被推测为Double类型@H_301_15@

当推断浮点数的类型时,Swift总是会选择Double而不是Float
如果表达式中同时出现了整数和浮点数,会被推断为Double类型。

let@H_301_15@ anotherPi = 3@H_301_15@ + 0.14159@H_301_15@
// anotherPi 会被推测为Double类型@H_301_15@

数值型字面量

整数字面量可以被写作:

  • 一个十进制数,没有前缀
  • 一个二进制数,前缀是0b
  • 一个八进制数,前缀是0o
  • 一个十六进制数,前缀是0x
    下面的所有整数字面量的十进制都是17:
let@H_301_15@ decimalInteger = 17@H_301_15@
let@H_301_15@ binaryInteger = 0@H_301_15@b10001
let@H_301_15@ octalInteger = 0@H_301_15@o21
let@H_301_15@ hexadecimalInteger = 0@H_301_15@x11

浮点字面量还有一个可选的指数,在十进制浮点数中通过大写或者小写的e来指定,在十六进制浮点数中通过大写或者小写的p来指定。
如果一个十进制数的指数为exp,那么这个数相当于基数和10^exp的乘积:

  • 1.25e2表示1.25 * 10^2,等于125.0
  • 1.25e-2表示1.25 * 10^-2,等于0.0125
    如果一个十六进制的指数为exp,那么这个数相当于基数和2^exp的乘积:
  • 0xFp2表示15 * 2^2,等于60.0
  • 0xFp-2表示15 * 2^-2,等于3.75
    下面这些浮点字面量都等于十进制的12.1875
let@H_301_15@ decimalDouble = 12.1875@H_301_15@
let@H_301_15@ exponentDouble = 1.21875@H_301_15@e1
let@H_301_15@ hexadecimalDouble = 0@H_301_15@xC.3@H_301_15@p0

数值类字面量可以包括额外的格式来增强可读性。整数和浮点数都可以添加额外的零并且包含下划线,并不会影响字面量:

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

数值型类型转换

整数转换

let@H_301_15@ cannotBeNegative: UInt8 =@H_301_15@ -@H_301_15@1@H_301_15@
// UInt8类型不能存储负数,所以会报错@H_301_15@
let@H_301_15@ tooBig: Int8 =@H_301_15@ Int8.@H_301_15@max@H_301_15@ +@H_301_15@ 1@H_301_15@
// Int8类型不能存储超过最大值的数,所以会报错@H_301_15@

整数和浮点数转换

let@H_301_15@ three = 3@H_301_15@
let@H_301_15@ point = 0.14159@H_301_15@
let@H_301_15@ pi = Double(three) + point
// pi等于3.14159,所以被推测为Double类型@H_301_15@

类型别名

typealias AudioSample =@H_301_15@ UInt16
var@H_301_15@ maxAmplitudeFound =@H_301_15@ AudioSample.@H_301_15@min@H_301_15@
// maxAmplitudeFound现在是0@H_301_15@

布尔值

let@H_301_15@ orangs = true@H_301_15@
let@H_301_15@ turn = false@H_301_15@

当你在编写条件语句比如if语句的时候,布尔值非常有用。

if@H_301_15@ turn {
    println@H_301_15@("ok"@H_301_15@);
} else@H_301_15@ {
    println@H_301_15@("no"@H_301_15@);
}

元组

元组把多个值组合成一个复合值。元组内的值可以是任意类型,并不要求是相同类型。

let@H_301_15@ http404Error = (404@H_301_15@,"Not Found"@H_301_15@)
// http404Error的类型是(Int,String),值是(404@H_301_15@,"Not Found"@H_301_15@)

可以将一个元组的内容分解成单独的常量和变量,然后就可以正常使用它们了:

let (statusCode,statusMessage) = http404Error
println@H_301_15@("The status code is \(statusCode)"@H_301_15@)
// 输出 "The status code is 404"@H_301_15@
println@H_301_15@("The status message is \(statusMessage)"@H_301_15@)
// 输出 "The status message is Not Found"@H_301_15@

如果只需要一部分元组值,分解的时候可以把要忽略的部分用下划线(_)标记

let@H_301_15@ (justTheStatusCode,_) = http404Error
println("The status code is \(justTheStatusCode)"@H_301_15@)
// 输出 "The status code is 404"@H_301_15@

此外,还可以通过下标来访问元组中的单个元素,下标从零开始:

println("The status code is \(http404Error.0)"@H_301_15@)@H_301_15@
// 输出 "The status code is 404"@H_301_15@
println("The status message is \(http404Error.1)"@H_301_15@)@H_301_15@
// 输出 "The status message is Not Found"@H_301_15@

可以在定义元组的时候给单个元素命名:

let@H_301_15@ http200Status = (statusCode: 200@H_301_15@,description: "OK"@H_301_15@)

给元组中的元素命名后,可以通过名字来获取这些元素的值:

println("The status code is \(http200Status.statusCode)"@H_301_15@)@H_301_15@
// 输出 "The status code is 200"@H_301_15@
println("The status message is \(http200Status.description)"@H_301_15@)@H_301_15@
// 输出 "The status message is OK"@H_301_15@

可选类型

举一个例子,Swift的String类型有一个叫toInt方法,作用是将一个String值转换为一个Int值,然而不是所有的字符串都可以转换为整数。字符串"123"可以被转换为数字123,但是字符串"Hello,World"不行。

let@H_301_15@ possibleNumber = "123"@H_301_15@
let@H_301_15@ convertedNumber = possibleNumber.toInt()
// convertedNumber被推测为类型"Int?"@H_301_15@

使用可选类型来处理值可能缺失的情况。一个可选的Int被写作Int?而不是Int。问号暗示包含的值是可选类型,也就是说可能包含Int值也可能不包含值。

if语句以及强制解析

可以使用if语句来判断一个可选是否包含值。如果可选类型有值,结果是true,如果没有值,结果是false
当你确定可选类型确实包含值之后,你可以在可选的名字后面加一个(!)来获取值。这个惊叹号表示我知道这个可选有值,请使用它,这被称为可选值得强制解析。

if@H_301_15@ convertedNumber != nil@H_301_15@ {
    println@H_301_15@("\(possibleNumber) has an integer value of \(convertedNumber)"@H_301_15@)
} else@H_301_15@ {
    println@H_301_15@("\(possibleNumber) could not be converted to an integer"@H_301_15@)
}
// 输出 "123 has an integer value of 123"@H_301_15@

可选绑定

使用可选绑定来判断可选类型是否包含值,如果包含就把值赋给一个临时常量或者变量。可选绑定可以用在ifwhile语句中来对可选类型的值进行判断并把值赋给一个常量或者变量。

if@H_301_15@ let actualNumber = possibleNumber.toInt() {
    println@H_301_15@("\(possibleNumber) has an integer value of \(actualNumber)"@H_301_15@)
} else@H_301_15@ {
    println@H_301_15@("\(possibleNumber) could not be converted to an integer"@H_301_15@)
}
// 输出 "123 has an integer value of 123"@H_301_15@

nil

可以给可选变量赋值为nil来表示它没有值:

var@H_301_15@ serverResponseCode: Int? = 404@H_301_15@
// serverResponseCode包含一个可选的Int值404@H_301_15@
serverResponseCode = nil@H_301_15@
// serverResponseCode现在不包含值@H_301_15@

nil不能用于非可选的常量和变量。如果你的代码中有常量或变量需要处理值缺失的情况,请把它们声明成对应的可选类型
如果你声明一个可选常量或变量但是没有赋值,它们会自动被设置为nil:

var@H_301_15@ surveyAnswer: String@H_301_15@?
// surveyAnswer被自动设置为nil@H_301_15@

Swift的nil和Objective-C中的nil并不一样。在Objective-C中,nil是一个指向不存在对象的指针。在Swift中,nil不是指针,它是一个确定的值,用来表示值缺失。任何类型的可选状态都可以被设置为nil,不只是对象类型。

隐式解析可选类型

有时候在程序架构中,第一次被赋值之后,可以确定一个可选类型总会有值。在这种情况下,每次判断和解析可选值是非常低效的,因为可以确定它总是会有值。
这种类型的可选状态被定义为隐式解析可选类型,把想要用作可选的类型的后面的问号改成惊叹号来声明一个隐式解析可选类型。

let@H_301_15@ possibleString: String@H_301_15@? = "An optional string."@H_301_15@
println(possibleString!) //需要惊叹号来获取值@H_301_15@
// 输出 "An optional string." @H_301_15@
let@H_301_15@ assumedString: String@H_301_15@! = "An implicitly unwrapped optional string."@H_301_15@
println(assumedString) //不需要惊叹号@H_301_15@
// 输出 "An implicitly unwrapped optional string."@H_301_15@

你仍然可以把隐式解析可选类型当做普通可选类型来检查并解析它的值:

if@H_301_15@ assumedString {
    println@H_301_15@(assumedString)
}
// 输出 "An implicitly unwrapped optional string."@H_301_15@

你也可以在可选绑定中使用隐式解析可选类型来检查并解析它的值:

if@H_301_15@ let@H_301_15@ definiteString = assumedString {
    println(definiteString)
}
// 输出 "An implicitly unwrapped optional string."@H_301_15@

断言

使用断言进行调试

let@H_301_15@ age = -3@H_301_15@
assert@H_301_15@(age >= 0@H_301_15@,"A person's age cannot be less than zero"@H_301_15@)
// 因为 age < 0, 所以断言会触发@H_301_15@

断言信息如果不需要,可以被省略:

assert(age >@H_301_15@= 0)@H_301_15@

何时使用断言

当条件可能为假时使用断言,但是最终一定要保证条件为真,这样你的代码才能继续运行。断言的适用情景:

  • 整数类型的下标索引被传入一个自定义下标脚本实现,但是下标索引值可能太小或太大。
  • 需要给一个函数传入一个值,但是非法的值可能导致函数不能正常执行。
  • 一个可选值现在是nil,但是后面的代码运行需要一个非nil值。

猜你在找的Swift相关文章