Swift3.0 - 真的很简单

让学习成为一种习惯

Swift源码下载地址

中文翻译文档 https://github.com/numbbbbb/the-swift-programming-language-in-chinese


基本数据类型

  • 使用let定义常量
let myConstant = 42

*使用var 定义变量

var myVariable = 42
myVariable = 50
  • 有初始化你可以指定变量类型或者让系统自己去推断
let implicitInteger = 70
let implicitDouble = 70.0
let explicitDouble: Double = 70
  • 没有初始化,你要必须指定变量类型
var numb:Double 
  • 在swift 中字符串是基本类型
let label = "The width is "
let width = 94
  • 如何实现数据之间的相互转换
let width = 94
let widthLabel:String = String(width)
  • 使用最简单的方式将其他数据类型编程字符串
let apples = 3
let oranges = 5
let fruitSummary = "I have \\(apples + oranges) pieces of fruit."
  • 数组也是基本类型,不再是OC中引用类型
var shoppingList = ["catfish", "water", "tulips", "blue paint"]
shoppingList[1] = "bottle of water"
  • 如何定义一个空数组
 let emptyArray = [String]()
 let emptyArray:[String] = []
  • 字典也是基本类型
var occupations = [
"Malcolm": "Captain",
"Kaylee": "Mechanic",
]
  • 将数组清空
 var shopingList1 = ["1","2"]
 shopingList1 = [] // 如果你这个类型,是系统可以推断的类型,你可以这样清空数组或者初始化
  • 定义一个空字典
let emptyDictionary = [String: Float]()
let emptyDictionary:[String: Float] = [:]
  • 清空字典
var dictionary = [1:"2"]
dictionary = [:]

可选值

let nickName: String? = nil 

"?" 这个简单意思,你的变量可能为nil,或者你可能将nil赋值给它,需要给变量定义的时候加上"?",否则一旦你将nil赋值给没有加"?"的变量,编译就会报错 举个例子理解一下,我们假如有一个盒子,盒子是一个存在的物体,swift不允许有空值出现,那我们怎么办呢?就需要把空值装到一个盒子里面,系统检查的时候,发现有一个盒子,哦,好的,检测通过,但是如果你把盒子打开系统就会报错

运行下面的代码:

let nickName: String? = "酷走天涯"
print(nickName)

结果:

Optional("酷走天涯")

发现有个Optional 就说明这个变量被包着,那么怎么才能不让它包裹着呢? 很简单, 给变量加一个"!"

print(nickName!)

运行:

酷走天涯


我们还有一种解包的方式

let nickName: String? = nil
let fullName: String = "XUJIE"
let informalGreeting = "Hi \\(nickName ?? fullName)"
print(informalGreeting)

运行 Hi XUJIE

如果第一个解包值发现为nil,则使用第二值

控制流

  • for ... in 循环
// 遍历数组
let individualScores = [75, 43, 103, 87, 12]
var teamScore = 0
for score in individualScores {
  if score > 50 {
      teamScore += 3
} else {
    teamScore += 1
}
}
print(teamScore)
// 遍历 字典
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest = 0
for (kind, numbers) in interestingNumbers {
    for number in numbers {
        if number > largest {
            largest = number
        }
    }
 }
 // 还可以这样使用循环
  var total = 0
 for i in 0..<4 {
   total += i
 }
 print(total)
  • Switch
 let vegetable = "red pepper"
switch vegetable {
case "celery":
    print("Add some raisins and make ants on a log.")
case "cucumber", "watercress":
    print("That would make a good tea sandwich.")
case let z where z.hasSuffix("pepper"):
    print("Is it a spicy \\(z)?")
default:
    print("Everything tastes good in soup.")
}

注意 z 什么 随便写个变量名就可以了

  • while 循环
var n = 2
  while n < 100 {
n = n * 2
}
print(n)
  • repeat ...while
 var m = 2
  repeat {
  m = m * 2
} while m < 100
print(m)

函数和闭包

*定义函数

func greet(person: String, day: String) -> String {
return "Hello \\(person), today is \\(day)."
}
greet(person: "Bob", day: "Tuesday")
  • 缺省参数名
func greet(_ person: String, _ day: String) -> String {
return "Hello \\(person), today is \\(day)."
}
greet("John", "Wednesday")
  • 返回值可以是元祖类型
func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
var min = scores[0]
var max = scores[0]
var sum = 0
for score in scores {
    if score > max {
        max = score
    } else if score < min {
        min = score
    }
    sum += score
}

return (min, max, sum)
}
let statistics = calculateStatistics(scores: [5, 3, 100, 3, 9])
print(statistics.sum)
print(statistics.2)
  • 定义多个类型相同的参数
func sumOf(numbers: Int...) -> Int {
var sum = 0
for number in numbers {
    sum += number
}
  return sum
}
sumOf()
sumOf(numbers: 42, 597, 12)
  • 函数嵌套使用
func returnFifteen() -> Int {
var y = 10
func add() {
    y += 5
}
// 方法内部定义方法,声明周期为方法
add()
return y
}
returnFifteen()
  • 函数当返回值
func makeIncrementer() -> ((Int) -> Int) {
    func addOne(number: Int) -> Int {
        return 1 + number
}
return addOne
}
var increment = makeIncrementer()
increment(7)
  • 函数当参数
 func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool {
for item in list {
    if condition(item) {
        return true
    }
}
return false
}
func lessThanTen(number: Int) -> Bool {
    return number < 10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(list: numbers, condition: lessThanTen)

对象和类

  • 定义一个类
class Shape {
var numberOfSides = 0
func simpleDescription() -> String {
    return "A shape with \\(numberOfSides) sides."
}
}
  • 初始化方法,和对象方法
class NamedShape {
    var numberOfSides: Int = 0
    var name: String
    // 初始化方法
    init(name: String) {
       self.name = name
    }
    // 成员方法定义
    func simpleDescription() -> String {
       return "A shape with \\(numberOfSides) sides."
    }
}
  • 继承
  class Square: NamedShape {
  var sideLength: Double  // 如果不是可选类型 必须在初始化方法中初始化

  init(sideLength: Double, name: String) {
    self.sideLength = sideLength
    super.init(name: name) // 调用父类的初始化方法
    numberOfSides = 4 // 给父类的属性赋值之前必须先调用父类的初始化方法
  }

  func area() ->  Double {
      return sideLength * sideLength
  }

    // 重写父类的方法
    override func simpleDescription() -> String {
        return "A square with sides of length \\(sideLength)."
    }
  }
  • setter 和 getter
class EquilateralTriangle: NamedShape {
var sideLength: Double = 0.0  // 定一个属性
init(sideLength: Double, name: String) {
    self.sideLength = sideLength
    super.init(name: name)
    numberOfSides = 3
    
}
 // 这个是setter 和geterr方法的定义
  var perimeter: Double {
    get {
         return 3.0 * sideLength
    }
    set {
        sideLength = newValue / 3.0
    }
    }

override func simpleDescription() -> String {
    return "An equilateral triangle with sides of length \\(sideLength)."
}
}
  • 观察属性
  class TriangleAndSquare {
  // 定一个三角形对象
  var triangle: EquilateralTriangle {
    willSet {
        square.sideLength = newValue.sideLength
    }
  }
  // 定一个一个正方形对象
  var square: Square {
    willSet {
        triangle.sideLength = newValue.sideLength
    }
  }
  // 通过检测属性,我们让两个对象的边保持一样长
  init(size: Double, name: String) {
    square = Square(sideLength: size, name: name)
    triangle = EquilateralTriangle(sideLength: size, name: name)
  }
  }
  var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
  print(triangleAndSquare.square.sideLength)
  print(triangleAndSquare.triangle.sideLength)
  triangleAndSquare.square = Square(sideLength: 50, name: "larger     square")
  print(triangleAndSquare.triangle.sideLength)

运行结果

10.0 10.0 50.0

枚举类型

  • 定义
enum Rank: Int { // Int 设置枚举值的类型
// 定义枚举值设置值
case ace = 1
// 可以case 后面一次定义多个枚举值
case two, three, four, five, six, seven, eight, nine, ten
case jack, queen, king

// 定义函数 如果多人合作的时候,可以使用这个让别人更加了解你定义的属性的含义
func simpleDescription() -> String {
    switch self { // self 就是这个枚举本身
        case .ace:
            return "ace"
        case .jack:
            return "jack"
        case .queen:
            return "queen"
        case .king:
            return "king"
        default:
            return String(self.rawValue)
    }
}
}
// 使用
let ace = Rank.ace
let aceRawValue = ace.rawValue

问题1 如何想OC 一样使用 | 或操作呢?


结构体

  • 定义
 struct Card {
// 定义结构体
    var rank: Rank
    var suit: Suit
// 结构体内可以定义方法
func simpleDescription() -> String {
    return "The \\(rank.simpleDescription()) of \\(suit.simpleDescription())"
}
}
  • 使用
let threeOfSpades = Card(rank: .three, suit: .spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()

协议

  • 定义
protocol ExampleProtocol {
     var simpleDescription: String { get }
     mutating func adjust()
}
  • 给类添加协议
class SimpleClass: ExampleProtocol {
 var simpleDescription: String = "A very simple class."
 var anotherProperty: Int = 69105
 func adjust() {
      simpleDescription += "  Now 100% adjusted."
 }
}
  • 给结构体添加协议
struct SimpleStructure: ExampleProtocol {
     var simpleDescription: String = "A simple structure"
 mutating func adjust() {
      simpleDescription += " (adjusted)"
 }
}
  • 定义一个协议变量
let protocolValue: ExampleProtocol = a
print(protocolValue.simpleDescription)

扩展

例子:给Int 添加一个协议

extension Int: ExampleProtocol {
var simpleDescription: String {
    return "The number \\(self)"
}
    mutating func adjust() {
        self += 42
    }
}
print(7.simpleDescription)

错误操作

  • 定义一个错误枚举
enum PrinterError: Error {
case outOfPaper
case noToner
case onFire
}
  • 定义一个有异常处理能力的函数
func send(job: Int, toPrinter printerName: String) throws -> String {
if printerName == "Never Has Toner" {
    throw PrinterError.noToner
}
return "Job sent"
}
  • 捕捉异常
do {
let printerResponse = try send(job: 1040, toPrinter: "Bi Sheng")
print(printerResponse)
} catch {
print(error)
}
  • 异常分类处理
 do {
let printerResponse = try send(job: 1440, toPrinter: "Gutenberg")
    print(printerResponse)
} catch PrinterError.onFire {
    print("I'll just put this over here, with the rest of the fire.")
} catch let printerError as PrinterError {
    print("Printer error: \\(printerError).")
} catch {
      print(error)
}

总结

Swift 的基本语法已经了解完毕,但这只是些简单的东西,如果Swift只是这些东西,那我们就没有学习的必要了,Swift的灵活性,优秀的设计模式,从上面的内容体现不出来,我会在后面几篇文章中,阐述它的高级用法!

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=3i4a1yo68wsg0

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术博客

C#基础知识系列九(对IEnumerable和IEnumerator接口的糊涂认识)

   IEnumerable、IEnumerator到现在为止对这两个接口还是不太理解,不理解但是自己总是想着试着要搞明白,毕竟自己用的少,所以在此先记录一下。...

1222
来自专栏Golang语言社区

【Go 语言社区】Golang 动态实例化结构体

但这里有一个限制:这个 map 仅仅可以用原型是“func()”的没有输入参数或返回值的函数。 如果想要用这个方法实现调用不同函数原型的函数,需要用到 inte...

41412
来自专栏知识分享

C#中public与private与static

现在静下心来想要重新细致的过一遍C#,因为自己做C#没有底气,, 闲话少说 先来一句话 public(共有的) 声明的方法和属性,可以被外部调用. privat...

3034
来自专栏个人随笔

那些年~~~我们的C#笔试内测题目

《深入.NET平台和C#编程》内部测试题-笔试试卷 一 选择题 1) 以下关于序列化和反序列化的描述错误的是( C)。 a) 序列化是将对象的状态存储到特定存储...

39911
来自专栏程序你好

C# 语言中Lambda(拉姆达) 表达式介绍

2044
来自专栏机器学习入门

POJ 刷题系列:2739. Sum of Consecutive Prime Numbers

POJ 刷题系列:2739. Sum of Consecutive Prime Numbers 传送门:POJ 2739. Sum of Consecutive...

2127
来自专栏Ryan Miao

Java8学习(3)- Lambda 表达式

猪脚:以下内容参考《Java 8 in Action》 本次学习内容: Lambda 基本模式 环绕执行模式 函数式接口,类型推断 方法引用 Lambda 复...

3359
来自专栏一枝花算不算浪漫

[读书笔记]C#学习笔记八:StringBuilder与String详解及参数传递问题剖析

37114
来自专栏海说

17、Map接口及其常用子类(Hashtable、HashMap、WeakHashMap)

17、Map接口   Map没有继承Collection接口,Map提供key到value的映射。一个Map中不能包含相同的key,每个key只能映射一个val...

2090
来自专栏Kiba518

C#语法——泛型的多种应用

泛型是.NET Framework 2.0 版类库就已经提供的语法,主要用于提高代码的可重用性、类型安全性和效率。

943

扫码关注云+社区

领取腾讯云代金券