官方文档
菜鸟教程
– 常量声明let i = 0
– 变量声明var i = 0
var msg:String
var msg:String = "msg"
– 单行 //...
– 多行/*......*/
– print("\(表达式)")
– 浮点数Double 64位
– 浮点数Float 32位
– 整数类型Int,Int8,Int16,UInt8,UInt16
– 布尔类型Bool
– 声明
let t = (1,"a")
– 访问
t.1
t.2
– 含义:表示有值或没有值nil
//创建
var str1 : String?//str1为nil
var str2 : String? = "msg"//str2为msg
str2 = nil //str2为nil
//强制取值
print(/(str2!))
//可选绑定
if let number = Int(possibleNumer){
//number是真实值,不为nil
}else{
//number为nil
}
do{
try ..
}catch Error{
...
}catch Error2{
...
}
condition?exp1:exp2
– a??b
等价于a != nil ? a! : b
a...b
for index in 1...5{
//todo
}
a..
for index in 0..<arr.count{
//todo
}
//索引2到结尾
for name in names[2...]{
//todo
}
//索引0到2
for name in names[...2]{
//todo
}
"""..."""
+
let c : Character = "!"
s.append(c)
\(表达式)
s.count
s.startIndex
s.index(before:s.endIndex)
s.index(after:s.startInex)
s.index(s.startIndex,offsetBy:7)
s.indices
s.insert(_:,at:)
s.insert(contentsOf:at:)
s[..
==
!=
hasPrefix()
hasSuffix()
可变性(引用和内容):可变var ,不可变let
//空的
var arr = [Int]()
//带指定值
var arr = [1,3,5]
//
+
arr.isEmpty
arr.count
//访问
arr[0]
//追加
arr.append()
//插入
arr.insert(123,at:0)
//删除
arr.remove(at:0)
//只元素
for item in arr{
//todo
}
//元素和索引
for (index,value) in arr.enumerate(){
//todo
}
//空的
var s = Set<Character>()
//带值
var s : Set = ["a","b","c"]
其他与Array类似
//空的
var dict = [Int:String]()
//带值
var dict = [1:"one",2:"two"]
//取值,返回optional
dict[1]
//添加或更新
dict[1] = "one"
if let oldValue = dict.updateValue("value",forKey:1){
//key存在则更新并返回旧值,不存在则返回nil
}
//删除键值对
dict[1] = nil
dict.removeValue(forKey:1)
for (k,v) in dict{}
for k in dict.keys{}
for v in dict.values{}
for _ in 1...5{
//todo
}
即do while
switch
中的case中隐式的加入了break,不需要break可以显式的加上fallthrough
,case可以有多个值
switch value{
case value1:
...
case value2,value3:
...
default:
...
}
//可以作为检验参数时使用
func f(person:[String,String]){
guard let name = person["name"] else {
return
}
}
func f(para1:String)->String{
return ""
}
func f(para1:String="hello")->String{
return ""
}
func f(para1:String){
}
func f(para1:String) -> (a:Int,b:Int){
return (a,b)
}
func f() -> String?{
//可以返回nil
}
func f() -> String{
"hello"
}
func f(para1:Int...) -> Int{
}
地址
传递)func f(para1:inout Int){
}
//当定义的函数为
func f(a:Int,b:Int)->Int{}
//函数f的类型为(Int,Int)->Int
//可以使用这种类型赋予变量
var v:(Int,Int)->Int = f
//或自动推断
var v = f
//函数类型可以作为参数
func f(AnotherF:(Int,Int)->Int){}
//函数类型可以作为返回值
func f() -> (Int)->Int{}
//可以在函数中定义函数
func f(){
func f1(){}
func f2(){}
}
简化函数类型作为参数传递
//sorted为例
//使用函数传递
func f(s1:String,s2:String)->Bool{s1>s2}
names.sorted(by:f)
//使用闭包表达式
names.sorted(by:{(s1:String,s2:String)->Bool in return s1>s2})
//进一步省略
names.sorted(by:{s1,s2 in s1>s2})
//参数名称缩写
names.sorted(by:{$0>$1})
//运算符方法
names.sorted(by:>)
//尾随闭包
names.sorted(){$0>$1}
//当只有一个参数时,括号也可以省略
names.sorted{$0>$1}
逃逸闭包
自动闭包
enum CompassPoint {
case north
case south
case east
case west
}
val s = CompassPoint.north
enum CompassPoint : CaseIterable{
case north
case south
case east
case west
}
//获取所有case:
CompassPoint.allCases
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
var productBarcode = Barcode.upc(8, 85909, 51226, 3)
逐一构造器
,结构体实例会有一个自动生成的逐一构造器
struct SPeople{
var age:Int
var name:String
}
class CPeople{}
var sp = SPeople()
var cp = CPeople()
.
p.name = ""
//被lazy修饰的属性,在第一次被访问到的时候才被创建
class C{
lazy var ...
}
获取该属性时,需要通过其他属性进行计算得到,设置改属性值时,其他属性的值可以发生变化
//例子:圆
struct Circle{
var r:Double = 0.0
var area:Double{
get{
return Double.pi*r*r
}
set(newArea){
r = sqrt(newArea/Double.pi)
}
}
}
//上面get可以省略return
//set可以使用默认的newValue参数,简化为
set{
r = sqrt(newValue/Double.pi)
}
//上面的计算属性area可以设置为只读,取消set
var area:Double{ Double.pi*r*r }
willSet
didSet
//默认参数newValue,oldValue
class C{
var v:Int=0{
willSet{
print("willSet:\(newValue)")
}
didSet{
print("didSet:\(oldValue)")
}
}
}
(类似java中的static)
struct/class S{
static var v = ""
}
//static 换成 class可以允许子类重写
class C{
class var v = ""
}
mutating
struct S{
var v = 0.0
mutating func f(){
v += 1
}
}
class C{
static func f(){}
class func f(){}//允许子类重写
}
相当于用下标的方式调用函数
struct S{
subscript(index:Int)->Int{
get{}
set{}
}
}
//如果是只读
subscript(index:Int)->Int{
return...
}
//调用
var s = S()
s[0]//get
s[0]=1//set
下标可以有多个参数,多种类型
subscript(a:Int,b:String)->Int{
get{}
set{}
}
static subscript
基本与Java类似
:
SuperClassoverride
super.
final
与Java类似
init
class A{
var i : Int = 0
init(i:Int){
self.i = i
}
}
override init(){
super.init()
...
}
用于初始化时没有指定属性值,默认初始化属性
class Food {
var name: String
init(name: String) {
self.name = name
}
convenience init() {
self.init(name: "[Unnamed]")
}
}
//调用
let f = Food()
//f.name为[Unnamed]
传入不符合条件的构造参数时,初始化失败
init?
该类的子类都必须实现该构造器
class C{
required init(){
//...
}
}
class D : C{
required init(){
//...
}
}
在实例被释放前需要执行的代码,每个类只能有一个析构器,析构器不能主动调用
deinit{
//...
}
//如果使用!强制展开可选值可能会引发错误
//代替方案为 :使用?
if let roomCount = john.residence?.numberOfRooms {
print("John's residence has \(roomCount) room(s).")
} else {
print("Unable to retrieve the number of rooms.")
}
func f() throws -> String{
//...
throw Error..
}
func f1() throws -> String{
//...
throw Error..
}
func f2() throws -> String{
//...
try f1()
}
func f2() throws -> String{
//...
do{
try f1()
}catch is XXXError{
//...
}
}
func f2() -> String{
//...
do{
try f1()
}catch XXXError{
//...
}catch XXXXError{
//...
}catch{
//...
}
}
//出错时x为nil
let x = try? f1()
//强制执行,不抛出
try!f1()
//退出代码块`{}`后执行的操作(延迟执行)
func open(filename) {
let file = open(filename)
defer {
close(file)
}
while let line = try file.readline() {
// 处理文件。
}
// close(file) 会在这里被调用,即作用域的最后。
}
is
item is Movie
as?
as!
item as? Movie //返回一个可选的Movie,转换失败则为nil
item as! Movie //强制转换为Movie类型
Any
和 AnyObject
//Any 可以表示任何类型,包括函数类型
//AnyObject 可以表示任何类类型的实例
内部类
为已经存在的类,结构体,枚举,协议添加新功能
新功能包括:
添加计算型实例属性和计算型类属性
定义实例方法和类方法
提供新的构造器
定义下标
定义和使用新的嵌套类型
使已经存在的类型遵循(conform)一个协议
//添加方法
extension Double{
var km:Double{
self*1000.0
}
}
//使用
var a = 1.2.km
//a的值为1200
类似Java interface
protocol P{
}
//父类名在协议前
class C : SuperClass,FirstProtocal,AnotherProtocal{}
协议中指定属性名,类型,可读写
protocol P{
var a : Int{get set}
var b : Int{get}
//类属性
static c : Int{get set}
}
protocol P{
func f() -> String
static func f() -> Int
}
protocol P{
init(para:Int)
}
//required不可少
class C : P{
required init(para:Int){
}
}
//如果同时继承
class C : Super,P{
required override init(para:Int){
}
}
protocol P : AnatherP{}
//如果继承AnyObject,那么该协议只能被类实现,不能被结构体实现
protocol P : AnyObject{}
//同时实现两个协议的类做为参数
func f(para:P1&P2){
}
@objc
通过extension
extension P{
}
some
//不使用some
struct ContentView : View{
var body : Text{
Text("hello")
}
}
//使用some
struct ContentView : View{
var body: some View{
Text("hello")
}
}
//这里的用some可以指定返回实现了View的类即可,避免在方法声明时就写上具体类型,方便更新维护
func f<T>(a:T,b:T) -> T{}
//泛型约束
T约束为子类或实现协议
func f<T : SuperClass,P>
associatedtype
protocol P{
associatedtype T
}
public
internal
默认的,模块内
file_private
private
//标明一个类型是可哈希化的,这样这个类型可以在Set,Dictionary中使用,因为需要这个类型的hashValue。hash后可以使用==操作符。
struct Person:Hashable{
var name:String
var id:Int
func hash(into hasher: inout Hasher) {
//需要用哪些属性进行hash计算,就combine进去,如果没有属性被combine进去,那么每个实例的hash值都是相同的
hasher.combine(name)
hasher.combine(id)
print("hash")
}
}
//类似于java的序列化,可以将实例编码为外部数据,也可以用外部数据解码生成实例
//例JSONEncoder ,JSONDecoder
let s = S(name: "a", id: 1)
let str = String(data: try! JSONEncoder().encode(s), encoding:.utf8)!
//str 为 {"name":"a","id":1}
let jsonStr = """
{"name":"a","id":1}
"""
let s2 = try JSONDecoder().decode(S.self, from:jsonStr.data(using: .utf8)!)
//s2为S(name: "a", id: 1)