热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Swift语言基础

swift基础swift简介xcode项目文件语法变量与常量类型安全强制类型转换运算符控制结构if语句switch语句循环结构数组字典函数inout传递和地址传递函数类型函数嵌套结

swift基础

  • swift简介
  • xcode项目文件
  • 语法
    • 变量与常量
      • 类型安全
      • 强制类型转换
    • 运算符
    • 控制结构
      • if语句
      • switch语句
    • 循环结构
    • 数组
    • 字典
    • 函数
      • inout传递和地址传递
      • 函数类型
      • 函数嵌套
    • 结构体和枚举
    • 闭包
    • 类和对象
      • 计算属性
      • 构造器和析构器
      • 继承
    • swift协议
    • swift拓展


swift简介

Swift 是一种支持多编程范式和编译式的开源编程语言,苹果于2014年WWDC(苹果开发者大会)发布,用于开发 iOS,OS X 和 watchOS 应用程序。

Swift 结合了 C 和 Objective-C 的优点并且不受 C 兼容性的限制。

Swift 在 Mac OS 和 iOS 平台可以和 Object-C 使用相同的运行环境。

官方手册:
swift官方手册
swift中文手册(5.0)

开发配置:xcode(开发工具),playground(编程环境)

xcode项目文件

launchscreen.storyboard:视图文件(一般是在app刚加载的时候一瞬间的闪现视图)

viewcontroller.swift:代码文件

info.plist:系统设置文件

main.stotyboard:视图文件

语法

变量与常量

注释:

// 单行注释/*
多行注释
*/

变量定义

var age = 18

常量定义

let age = 19

常见数据类型

类型关键字
整形Int
浮点型Double
布尔型Bool
字符串型String

类型安全

值推断

// 自动推断为整形
let age = 13
var age = 19

类型声明

let age:Int = 13
var high:Double = 1.2
var name:String = "swift"
var t:Bool = false

强制类型转换

var m:Double = 1.5
var n:Int = (Int)m + 1

运算符

和:&&
非:!
或:||

控制结构


if语句

var p = 1
if p > 1 {print(1)
}
else if p < 1 {print(0)
}
else {print(2)
}

switch语句

var p &#61; 1
switch p {case 0:print(0)case 1:print(1)case 2:print(2)default:print(false)
}

其他写法

var m &#61; "o"
switch m {case "a", "e", "i", "u", "e":print(true)default:print(false)
}var n &#61; 34
switch n {case 0...100: // 包括100print(true)case 101..< 200: // 不包括200print(false)default:print("none")
}var p &#61; 12
switch p {case Int.min...13:print(true)default:print(false)
}

循环结构

for in

var arr:[Int] &#61; [1, 2, 3]
for f in arr {print(f)
}

while

var i &#61; 0
while i < 10 {print(i)i &#43;&#61; 1
}

数组

创建一个数组

// 1
var arr &#61; [Int]()
// 2
var arr:[Int] &#61; [1, 3, 4]
// 3
var arr &#61; [Int](repeating: 10, count: 2)

修改数组

// 添加元素
var arr &#61; [Int]()
arr.append(2)
arr.append(3)
arr &#43;&#61; [4]
// 合并数组
var ar1 &#61; [Int](repeating: 1, count: 3)
var ar2 &#61; [Int](repeating: 2, count: 10)
var ar3 &#61; ar1 &#43; ar2

字典

创建字典

// 1
var someDict &#61; [Int: String]()
// 2
var someDict:[Int:String] &#61; [1:"One", 2:"Two", 3:"Three"]

修改字典

// 添加或更新元素
var someDict:[Int:String] &#61; [1:"One", 2:"Two", 3:"Three"]
var oldVal &#61; someDict.updateValue("One 新的值", forKey: 1)// 移除元素
var someDict:[Int:String] &#61; [1:"One", 2:"Two", 3:"Three"]
// 1
var removedValue &#61; someDict.removeValue(forKey: 2)
// 2
someDict[2] &#61; nil

遍历字典

var someDict:[Int:String] &#61; [1:"One", 2:"Two", 3:"Three"]for (key, value) in someDict {print("字典 key \(key) - 字典 value \(value)")
}

字典转换成数组

var someDict:[Int:String] &#61; [1:"One", 2:"Two", 3:"Three"]let dictKeys &#61; [Int](someDict.keys)
let dictValues &#61; [String](someDict.values)

还有count判断键值对个数&#xff0c;isEmpty()判断是否为空

函数

func funcname(形参) -> returntype
{Statement1Statement2……Statement Nreturn parameters
}

函数调用

func runoob(site: String) -> String {return (site)
}
print(runoob(site: "www.runoob.com"))

返回值类型

// 元组
func minMax(array: [Int]) -> (min: Int, max: Int)? {if array.isEmpty { return nil }var currentMin &#61; array[0]var currentMax &#61; array[0]for value in array[1..<array.count] {if value < currentMin {currentMin &#61; value} else if value > currentMax {currentMax &#61; value}}return (currentMin, currentMax)
}
if let bounds &#61; minMax(array: [8, -6, 2, 109, 3, 71]) {print("最小值为 \(bounds.min)&#xff0c;最大值为 \(bounds.max)")
}// 无返回值
func runoob(site: String) {print("菜鸟教程官网&#xff1a;\(site)")
}
runoob(site: "http://www.runoob.com")

参数范围

// 局部函数参数&#xff0c;number 为局部参数名&#xff0c;只能在函数体内使用
func sample(number: Int) {print(number)
}
sample(number: 1)
sample(number: 2)
sample(number: 3)// 外部函数参数名&#xff0c;在局部参数名前指定外部参数名&#xff0c;中间以空格分隔&#xff0c;外部参数名用于在函数调用时传递给函数的参数
func pow(firstArg a: Int, secondArg b: Int) -> Int {var res &#61; afor _ in 1..<b {res &#61; res * a}print(res)return res
}
pow(firstArg:5, secondArg:3)

inout传递和地址传递

一般默认在函数中定义的参数都是常量参数&#xff0c;也就是这个参数你只可以查询使用&#xff0c;不能改变它的值。

如果想要声明一个变量参数&#xff0c;可以在参数定义前加 inout 关键字&#xff0c;这样就可以改变这个参数的值了

func getName(_ name: inout String).........

一般默认的参数传递都是传值调用的&#xff0c;而不是传引用。所以传入的参数在函数内改变&#xff0c;并不影响原来的那个参数。传入的只是这个参数的副本。

当传入的参数作为输入输出参数时&#xff0c;需要在参数名前加 & 符&#xff0c;表示这个值可以被函数修改

func swapTwoInts(_ a: inout Int, _ b: inout Int) {let temporaryA &#61; aa &#61; bb &#61; temporaryA
}var x &#61; 1
var y &#61; 5
swapTwoInts(&x, &y)
print("x 现在的值 \(x), y 现在的值 \(y)")

函数类型

在 Swift 中&#xff0c;使用函数类型就像使用其他类型一样。例如&#xff0c;你可以定义一个类型为函数的常量或变量&#xff0c;并将适当的函数赋值给它

var addition: (Int, Int) -> Int &#61; sum

函数嵌套

func calcDecrement(forDecrement total: Int) -> () -> Int {var overallDecrement &#61; 0func decrementer() -> Int {overallDecrement -&#61; totalreturn overallDecrement}return decrementer
}
let decrem &#61; calcDecrement(forDecrement: 30)
print(decrem())

结构体和枚举

在此不做叙述

闭包


类和对象


计算属性

除存储属性外&#xff0c;类、结构体和枚举可以定义计算属性&#xff0c;计算属性不直接存储值&#xff0c;而是提供一个 getter 来获取值&#xff0c;一个可选的 setter 来间接设置其他属性或变量的值

class sample {var no1 &#61; 0.0, no2 &#61; 0.0var length &#61; 300.0, breadth &#61; 150.0var middle: (Double, Double) {get{return (length / 2, breadth / 2)}set(axis){no1 &#61; axis.0 - (length / 2)no2 &#61; axis.1 - (breadth / 2)}}
}
var result &#61; sample()
print(result.middle)
result.middle &#61; (0.0, 10.0)print(result.no1)
print(result.no2)

如果计算属性的 setter 没有定义表示新值的参数名&#xff0c;则可以使用默认名称 newValue

只读计算属性
只有 getter 没有 setter 的计算属性就是只读计算属性。

只读计算属性总是返回一个值&#xff0c;可以通过点(.)运算符访问&#xff0c;但不能设置新的值。

class film {var head &#61; ""var duration &#61; 0.0var metaInfo: [String:String] {return ["head": self.head,"duration":"\(self.duration)"]}
}var movie &#61; film()
movie.head &#61; "Swift 属性"
movie.duration &#61; 3.09print(movie.metaInfo["head"]!)
print(movie.metaInfo["duration"]!)

全局变量(static关键字)

struct Structname {static var storedTypeProperty &#61; " "static var computedTypeProperty: Int {// 这里返回一个 Int 值}
}enum Enumname {static var storedTypeProperty &#61; " "static var computedTypeProperty: Int {// 这里返回一个 Int 值}
}class Classname {class var computedTypeProperty: Int {// 这里返回一个 Int 值}
}

属性观察器

可以为属性添加如下的一个或全部观察器&#xff1a;

  • willSet在设置新的值之前调用
  • didSet在新的值被设置之后立即调用
  • willSet和didSet观察器在属性初始化过程中不会被调用

class Samplepgm {var counter: Int &#61; 0{willSet(newTotal){print("计数器: \(newTotal)")}didSet{if counter > oldValue {print("新增数 \(counter - oldValue)")}}}
}
let NewCounter &#61; Samplepgm()
NewCounter.counter &#61; 100
NewCounter.counter &#61; 800

注意&#xff1a;
不需要为无法重载的计算属性添加属性观察器&#xff0c;因为可以通过 setter 直接监控和响应值的变化。


构造器和析构器

// 构造器
init() {// do something
}
// 析构器
deinit() {// do something
}

继承

class a {// do something
}
class b: a {// do something
}

重写
子类可以通过继承来的实例方法&#xff0c;类方法&#xff0c;实例属性&#xff0c;或下标脚本来实现自己的定制功能&#xff0c;我们把这种行为叫重写&#xff08;overriding&#xff09;

通过使用super前缀来访问超类的方法&#xff0c;属性或下标脚本。

重写访问方法&#xff0c;属性&#xff0c;下标脚本
方法super.somemethod()
属性super.someProperty()
下标脚本super[someIndex]

class SuperClass {func show() {print("这是超类 SuperClass")}
}class SubClass: SuperClass {override func show() {print("这是子类 SubClass")}
}let superClass &#61; SuperClass()
superClass.show()let subClass &#61; SubClass()
subClass.show()

swift协议

协议规定了用来实现某一特定功能所必需的方法和属性。

任意能够满足协议要求的类型被称为遵循(conform)这个协议。

类&#xff0c;结构体或枚举类型都可以遵循协议&#xff0c;并提供具体实现来完成协议定义的方法和功能。

协议定义

protocol SomeProtocol {// 协议内容
}

遵循协议

struct SomeStructure: FirstProtocol, AnotherProtocol {// 结构体内容
}
class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol {// 类的内容
}

对属性的规定

protocol classa {var marks: Int { get set }var result: Bool { get }func attendance() -> Stringfunc markssecured() -> String}protocol classb: classa {var present: Bool { get set }var subject: String { get set }var stname: String { get set }}class classc: classb {var marks &#61; 96let result &#61; truevar present &#61; falsevar subject &#61; "Swift 协议"var stname &#61; "Protocols"func attendance() -> String {return "The \(stname) has secured 99% attendance"}func markssecured() -> String {return "\(stname) has scored \(marks)"}
}let studdet &#61; classc()
studdet.stname &#61; "Swift"
studdet.marks &#61; 98
studdet.markssecured()print(studdet.marks)
print(studdet.result)
print(studdet.present)
print(studdet.subject)
print(studdet.stname)

不做过多叙述&#xff0c;详情可见swift协议规范

swift拓展

扩展就是向一个已有的类、结构体或枚举类型添加新功能。

扩展可以对一个类型添加新的功能&#xff0c;但是不能重写已有的功能。

Swift 中的扩展可以&#xff1a;

  • 添加计算型属性和计算型静态属性
  • 定义实例方法和类型方法
  • 提供新的构造器
  • 定义下标
  • 定义和使用新的嵌套类型
  • 使一个已有类型符合某个协议

extension SomeType {// 加到SomeType的新功能写到这里
}

详情可见swift拓展


推荐阅读
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
author-avatar
伴生约定_879
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有