关于swift的个人小结

写在前面

接触swift也有段时间了,通过这段时间自己接触和借鉴别人的经验,记录几点关于swift的小技巧,虽然不是什么高深的原理知识,但是在平常的项目中用到或许可以提高开发效率呢

🙃,哈哈,接下来就简单总结一下:

枚举(ENUM)

结合一个小场景, 比如我们要做一个关于性别判断的一个小case:
可能我们首先想到的就是这样,硬编码写入,每次都需要手动输入

var gender = ""
gender = "man"
switch gender {
case "man":
  print("man")
  case "female":
  print("female")
default:
  print("other")
}

但是如果我们利用枚举来写的话:

enum Gender {
  case man
  case female
  case other
}
var gType: Gender = .man
switch gType {
case .man:
  print("男性")
case .female:
  print("女性")
case .other:
  print("其他类型")
default:
  print("我也不知道")
}

把需要的类型写到enum 中,就会减少不小心输入错误的几率,而且不在enum范围中的实例,编辑器也会指出。

空合运算符

比如我们要定义某个label的默认text, 也就是说,如果我们没有去人为设置,这个label就会用默认text显示,我们可能会这么写:

var customText: String?
var defaultText = "您好"
var textToUse = ""
if let text = customText {
  textToUse = text
} else {
  textToUse = defaultText
}

如果换种简单的写法就成了这样:

var customText: String?
var defaultText = "您好"
var textToUse = ""
var textToUse = customText ?? defaultText

?? 的意思就是如果textToUse为nil则选择defaultText 否则选择customText

函数式

比如我们获取10以内的奇数, 第一想法是,用for循环呀:

var arr = [Int]()
for i in 1...10 {
  if i % 2 == 1 {
    arr.append(i)
  }
}
print(arr)

当然了,必然可以计算出结果,如果换种思路呢,swift内置filter函数:

var arr = (1...10).filter { (num) -> Bool in
  num % 2 == 1
}
print(arr)

闭包 \ 函数

举个栗子,两个字符串拼接

使用函数:

func sum(a: String, b: String) -> String {
  return a + b
}
var result = sum(a: "你好", b:"哈哈哈")

如果使用闭包的话:

var sumStringClosure: (String, String) -> String = {
  $0 + $1
}
sumStringClosure("hello", "world")

有木有感觉easy了好多

convenience init 便利初始化

我们声明一个类,给这个类设置变量然后将其初始化

class Animal {
  var dog: Int?
  var cat: Int?
  init(dog: Int, cat: Int) {
    self.dog = dog
    self.cat = dog
  }
}
var daDi = Animal(dag: 2, cat: 4)
daDi.dog
daDi.cat

假如我们想在每次用到 Animal这个类的时候,我们想着给这个类中的dog和cat都设置好数量,我们就可以用convenience init来设置

class Animal {
  var dog: Int?
  var cat: Int?
  init(dog: Int, cat: Int) {
    self.dog = dog
    self.cat = dog
  }
  convenience init() {
    self.init(dog: 10, cat: 10)
  }
}

var daDi = Animal()
daDi.dog
daDi.cat

属性观察

自从swift更新到swift3之后 我们发现 变量的set\get方法发生改变了有木有,添加了一个很方便的属性就是willSet和didSet,比如我们如果求一个正方形的周长,使用function的话是这样子的 :

var length :Double?
func getDiameter(length: Double) -> Double {
  return length * 4
}
getDiameter(length: 10)

如果我们使用变量的属性观察方法:

var perimeter: Double?
var length: Double? {
willSet {
  print("准备赋值中")
}
didSet {
  perimeter = length! * 4
}
}
length = 20
perimeter

willSet
是在属性发生改变之前调用的
didSet
是在属性发生改变之后调用的。

遍历方法

打印字符串:如果使用while 来

var i = 0
while i < 5 {
  print("irembeu")
  i += 1
}

我们必须要定义一个变量来确保打印达到我们要求的次数,但是我们定义越多的变量就意味着出错的风险越大,所以还是尽量少写点儿代码,改成for循环版:

for _ in 1...10 {
  print("itembeu")
}

不需要我们定义多余变量,因为swift语法设计的时候用_来代替可以忽略的变量了

计算属性\ 函数

取圆的直径和半径:
1、使用函数:在这种情况下,我们根据半径求直径,根据已经直径求半径,需要写两个function

func getDiameter(radius: Double) -> Double { return radius * 2}
func getRadius(diameter: Double) -> Double { return diameter / 2}
getDiameter(radius: 20)
getRadius(diameter: 100)

2、使用变量的计算属性

var radius: Double = 10
var diameter: Double {
  get {
    return radius * 2
    }
  set {
    radius = newValue / 2
    }
}
radius // 20
diameter // 40
diameter = 600
radius // 300

我们知道直径和半径是相互依存的关系的,使用变量的计算属性这样看起来要比使用函数计算要简洁的多了。

泛型

如果我们需要将不同类型数组中的变量打印输出,我们可能会这样做:

var stringArr = ["骑士", "湖人", "公牛"]
var intArr = [1, 3, 4, 5, 6]
var doubleArr = [1.0, 2.0, 3.0]
func printStringArr(a: [String]) { for s in a { print(s) } }
func printIntArr(a: [Int]) { for i in a { print(i) } }
func printDoubleArr(a: [Double]) {for d in a { print(d) } }

我们需要定义不同类型的数组,如果类型多了,那我们做的无谓的工作就有点儿多了,这时候我们如果使用泛型来解决这个问题的话:

func printElementFromArr<T>(elements: [T]) {
  for e in elements {
    print(e)
  }
}
printElementFromArr(elements: [1,2,3,4])

简单好多 有木有, 泛型是Swift语言强大的核心,泛型是对类型的抽象,使用泛型开发者可以更加灵活方便的表达代码意图。有参函数的参数必须有一个明确的参数类型,有些时候开发者会遇到这样一种情况,就像上面我们举的这个例子,由于变量有类型之分,实现相同的功能,可能需要重载成多个函数来实现,这大大浪费了开发成本,使用泛型,可以完美的解决这个问题。

拓展

swift 中没有了OC中的category 但是保留了extension, 我们和extension打交道的时候也就比较多了, 如果我们需要计算一个数的平方,我们可以声明一个函数, 像这样:

func squ(x: Int) -> Int {
  return x * x
}
var s = squ(x: 10)

那如果我们要求10 的4次方的话,我们就要var s = squ(x: 10)
squ(x: s)创建多余变量。
使用拓展:

extension Int {
  var squ: Int {
    return self * self
  }
}
10.squ
10.squ.squ

简洁,不需要多创建变量。

Gaurd let \ if let

检验用户名和密码:

1、使用if let, 我们需要一层层的嵌套

var uName: Double?
var uPassword: Double?
func userLogIn() {
  if let username = uName {
    if let password = uPassword {
      print("欢迎, \(username)"!)
    }
  }
}

2、使用gaurd let, 如果uName或者uPassword为nil的话,程序就会走return方法,提前结束运行, 否则就会print("欢迎, \(username)!")

var uName: Double?
var uPassword: Double?
func userLogIn() {
   guard let username = uName, let password = uPassword
     else { return }
    print("欢迎, \(username)!")
}
(0)

相关推荐

  • swift中的正则表达式小结

    作为一门先进的编程语言,Swift 可以说吸收了众多其他先进语言的优点,但是有一点却是让人略微失望的,就是 Swift 至今为止并没有在语言层面上支持正则表达式. 正则表达式的用处: 判断给定的字符串是否符合某一种规则(专门用于操作字符串) - 电话号码,电子邮箱,URL... - 可以直接百度别人写好的正则 - 别人真的写好了,而且测试过了,我们可以直接用 - 要写出没有漏洞正则判断,需要大量的测试,通常最终结果非常负责 过滤筛选字符串,网络爬虫 替换文字,QQ聊天,图文混排 语法规则 使用过

  • Swift 共享文件操作小结(iOS 8 +)

    前言 适用于 iOS 8 + 本地共享文件列表 正文 一.准备 1.1 默认 App 的文件共享是关闭的,需要在 plist 中设置启用: Application supports iTunes file sharing 设置为 YES 启用后把设备连接到 iTunes 上,在 iTunes 应用里的文件共享就能看到你的 App 了(如果看不见需要断开重新拔插一下数据线),可以拷贝一些视频进去,便于测试. 1.2 导入库 Photos.framework AVKit.framework 用于播放

  • 关于swift的个人小结

    写在前面 接触swift也有段时间了,通过这段时间自己接触和借鉴别人的经验,记录几点关于swift的小技巧,虽然不是什么高深的原理知识,但是在平常的项目中用到或许可以提高开发效率呢

  • Swift 4中一些实用的数组技巧小结

    前言 Swift提供了两种集合类型来存放多个值--数组(Array)和字典(Dictionary).这个大家应该都知道,在年前的时候,买了本Swift 进阶(swift4.0),过完年回来正在一点点学习,不得不说喵神写的东西还是不错的,¥69元对广大程序员来说已经不算啥了.如果感兴趣可以买一本,真心不错 当我从头来学习数组的时候发现好多函数真的太有用了,下面话不多说了,来一起看看详细的介绍吧. Swift 4.0 中的可变数组技巧 我们可用 Xcode 创建playground 来进行练习 首先

  • Swift中初始化init的方法小结

    前言 我们在深入初始化方法之前,不妨先再想想Swift中的初始化想要达到一种怎样的目的. 其实就是安全.在Objective-C中,init方法是非常不安全的:没有人能保证init只被调用一次,也没有人保证在初始化方法调用以后,实例的各个变量都完成初始化,甚至如果在初始化里使用属性进行设置的话,还可能会造成各种问题.虽然Apple也明确说明了不应该在init中使用属性来访问,但这并不是编译器强制的,因此还是会有很多开发者犯这样的错误. 所以Swift有了超级严格的初始化方法.一方面,Swift强

  • swift中defer的实际应用小结

    看看苹果官方的介绍 用 defer 语句在即将离开当前代码块时执行一系列语句.该语句让你能执行一些必要的清理工作,不管是以何种方式离开当前代码块的--无论是由于抛出错误而离开,或是由于诸如 return.break 的语句.例如,你可以用 defer 语句来确保文件描述符得以关闭,以及手动分配的内存得以释放. defer 语句将代码的执行延迟到当前的作用域退出之前.该语句由 defer 关键字和要被延迟执行的语句组成.延迟执行的语句不能包含任何控制转移语句,例如 break.return 语句,

  • 理解二叉堆数据结构及Swift的堆排序算法实现示例

    二叉堆的性质 1.二叉堆是一颗完全二叉树,最后一层的叶子从左到右排列,其它的每一层都是满的 2.最小堆父结点小于等于其每一个子结点的键值,最大堆则相反 3.每个结点的左子树或者右子树都是一个二叉堆 下面是一个最小堆: 堆的存储 通常堆是通过一维数组来实现的.在起始数组为 0 的情形中: 1.父节点i的左子节点在位置 (2*i+1); 2.父节点i的右子节点在位置 (2*i+2); 3.子节点i的父节点在位置 floor((i-1)/2); 维持堆的性质 我们以最大堆来介绍(后续会分别给出最大堆和

  • Swift源码解析之弱引用

    序言: 各个社区有关 Objective-C weak 机制的实现分析文章有很多,然而 Swift 发布这么长时间以来,有关 ABI 的分析文章一直非常少,似乎也是很多 iOS 开发者未涉及的领域- 本文就从源码层面分析一下 Swift 是如何实现 weak 机制的. 下面话不多说了,来一起看看详细的介绍吧 准备工作 由于 Swift 源码量较大,强烈建议大家把 repo clone 下来,结合源码一起来看这篇文章. $ git clone https://github.com/apple/sw

  • C++轻量级界面开发框架ImGUI介绍小结

    目录 ImGUI简介 ImGUI的界面实现 技术选型 如何使用ImGUI   如果从事过C++ Windows客户端开发,大家对MFC.Qt.DuiLib等各种DirectUI应该有了解,本篇给大家介绍一个超级轻量级的C++开源跨平台图形界面框架ImGUI. ImGUI简介   ImGUI主要用于游戏行业,所有的控件都需要手绘实现,当然性能也是满满的,毕竟是直接用dx/opengl来实现. ImGUI仓库:https://github.com/ocornut/imgui   ImGUI又称为De

  • iOS Swift读取本地json文件报错的解决方法

    前言 最近闲来无聊,本地了一个json读取,但没想到在用Swift测试数据发现加载本地json文件一直报以下错误: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with a

随机推荐