一.集合
1.集合的基本定义:
var a : Set<Int> = [1,2,3,4,2,3]
如果你打印出来,并不会有相同的元素出现
print(a)
结果就会是:[1,2,3,4]
2.遍历集合
for x in a{
print(x)
}
遍历出来也不会有相同的元素出现
3.添加元素和删除元素
就一上面的a数组为例,添加元素:
a.insert(9)
同理删除元素:
a.remove(2)
4.并集,交集,差集,判断子集
仍然以还是那个面的a集合为例
var b:Set<Int> = [2,3,4,7,9,11]
print(a.intersect(b))//并集
print(a.union(b))//交集
print(a.subtract(b))//差集(a有而b没有的元素)
print(b.isSubsetOf(a))//判断子集
二.字典(Dictionaries)
1.定义和组成:
存放键值对组合的容器,字典中的每一个元素都是由两部分构成的,冒号前面是键,冒号后面是值
var dict = ["abacus":"算盘","abnormal":"异常的","hello":"你好","good":"你好"]
通过键获取对应的值(可空类型,因为给的键有可能没有与之对应的值):key-->value
####2.在字典中加键,删除键,修改元素
print(dict["hello"]!)
print(dict["ashdg"])
dict["shit"] = "狗屎" //在字典里面加一个键
dict.removeValueForKey("hello")//删除一个键
dict["hello"] = nil//这样也是阔以的
//修改里面的元素
dict["shit"] = "牛粪"
3.遍历字典中的值,键,值和键
遍历字典中所有的值
for value in dict.values{
print(value)
}
遍历字典中所有的键
for key in dict.keys{
print("\(key)--->\(dict[key])")
}
遍历字典中所有的键和对应的值
for (key,value) in dict{
print("\(key)--->\(value)")
}
三.函数
1.函数的定义
独立的,能重复的使用的功能模块。
基本形式:func 函数名 (参数列表) -> 返回元素{函数的执行体}。
函数名 (外部参数名 内部参数名:类型,外部参数名,内部参数名:类型)
注:可以使用_来作为外部参数名表示省略外部参数名。
func sayHello( personName: String,
alreadyGreeted:Bool = false) ->String{
//let greeting = "Hello, " + personName + "!"
//如果函数的返回类型不是void,那么函数中一定有return语句
//return greeting
//personName:"王小锤" 会产生编译错误
if alreadyGreeted{
return"怎么又是你, " + personName + "!"
}
else{
return "你好," + personName + "!"
}
return "Hello, " + personName + "!"
}
//调用函数,写出函数的名字,加上参数的值就可以了
print(sayHello("王大锤", alreadyGreeted: true))
let str = (sayHello("蒋渣渣"))//可以给参数指定默认值,如果函数的使用的时候没有给参数辅值就直接使用默认值,就像这里的false
2.函数的基本使用方法
func min1(x: Int,b y: Int) -> Int{
return x < y ? x : y
}
//调用时要用外部参数名b,如果不写b,内外参数名一致的
print(min1( 3,b: 5))
func sum(nums: Int...) -> Int{//可变参数列表,参数的数量可以为任意个...
var total = 0
for num in nums {
total += num
}
return total
}
print(sum())
print(sum(999))
print(sum(1,2,3,5,6))
//可以使用元组(tuple)来让一个函数返回多个数据
func minMax(array: [Int]) -> (min: Int, max: Int)? {
if array.count == 0 {
return nil
}
var currentMin = array[0]
var currentMax = array[0]
for value in array[1..<array.count] {
if value < currentMin {
currentMin = value
}
else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}if let b = minMax([4823,34,849,8440,9498,]){
print(b.min) //print(b.0)
print(b.max) //print(b.1)
}
else{
print("数组中没有元素!!!")
}
func swap(inout a: Int,inout b: Int) -> Void{
// let temp = a
// a = b
// b = temp
(a,b) = (b,a)
}
//函数调用的传参都是传值
var a = 5, b = 10
swap(&a, &b)
print("a = \(b)")
print("b = \(a)")
func createX(inout x : Int){//inout - 输入输出参数(不仅将数据传入函数中还要从函数中取出数据)
x = 1000
}
var x = 1
createX(&x)
print(x)
3.相关练习:
练习一:设计一个函数传入两个整数m和n(n>m),计算m加到n的和
func sum(m:Int,_ n:Int) -> Int{
let (a,b) = m > n ? (n,m) : (m,n)
var value = 0
for i in a...b{
value += i
}
return value
}
print(sum(1,100)
练习二:设计一个函数输入三条变得长度,判断能不能构成三角形
func triangle(a: Double,_ b:Double,_ c:Double ) ->Bool{
assert(a > 0 && b > 0 && c > 0,"三角形的边长必须大于0")
if a + b > c && a - b < c {
return true
}
else{
return false
}
}
print(triangle(3.0,2.0,5.0))
练习三:
设计一个函数传入年月日返回该日期是这一年的第几天
func daysofYear(year: Int,month: Int,day: Int) ->Int{
var day1 = 0
var array = [31,28,31,30,31,30,31,31,30,31,31,30]
if year % 4 == 0 && year % 100 != 0 || year % 400 == 0 {
array[1] = 29
}
for i in 0..<month - 1{
day1 += array[i]
}
day1 += day
return day1
}
print(daysofYear(200, month: 3, day: 1))
练习四
设计一个函数计算组合数c(m,n) = m!/n!/(m-n)!
//求阶乘
func factorial(n: Int) -> Double{
var val = 1.0
var i = 2
while i <= n{
val *= Double(i)
i += 1
}
return 0.0
}
func combine(m:Int,n:Int) -> Double{
assert(m >= n,"m必须大于等于n")//断言
var b:Double
b = factorial(m) / factorial(n) / factorial(m-n)
return b
}
func factorial(a: Int) -> Double{
var val = 1.0
var i = 1 //函数的递归调用(一个函数直接或者间接的调用自身)
//1.递归公式 2.收敛条件
while i <= a{ //if n == 0 || n == 1{
//return 1
// }
val *= Double(i) // return Double(n) * f (n - 1)
i += 1
}
return val
}
print(combine(3, n: 2))
4.函数的扩展(函数也可以作为参数使用,闭包)
func sum(a: Int,_ b: Int) -> Int {
return a + b
}
func mul(a: Int,_ b: Int) -> Int{
return a * b
}
//var fn: (Int,Int) ->Int = sum
//fn(2,3)
//fn = mul
//fn(2,3)
func foo(array: [Int],fn: (Int,Int) ->Int) -> Int {
var sum = array[0]
for x in array[1..<array.count] {
sum = fn(sum,x)
}
return sum
}
let a = [1,2,3,4,5]
// 1.所有自定义的(Int,Int)-> Int类型的函数
print(foo(a, fn: sum))
// 2.传入二元运算符:+—*/%(因为运算符也是函数)
print(foo(a, fn: +))
// 3.传入匿名函数(闭包)
// 3.1 完整的闭包写法
print(foo(a, fn: { (a: Int,b: Int) -> Int in
return a + b
}))
// 3.2 省略掉类型和不必要的括号
print(foo(a, fn: {a, b in a+b}))
// 3.3 省略参数名
print(foo(a, fn: {$0 + $1}))
// 3.4 尾随闭包
print(foo(a) {$0 + $1})
print(foo(a) { (a, b) -> Int in
return a + b
})
var array = ["game","abacus","hello","cat","good","dislike"]
array.sortInPlace(>)
array.sortInPlace({$0 > $1})
array.sortInPlace() {$0 > $1}
array.sortInPlace {$0 > $1}
4.尾随闭包
如果函数的最后一个参数是闭包可以写成尾随闭包的形式
也就是将闭包放到函数参数的圆括号外面写在一堆花括号中
如果函数后面有尾随闭包且函数的圆括号中没有参数
那么函数的圆括号也可以省略(仅限于有尾随闭包的场景)
array.sortInPlace {
if $0.characters.count == $1.characters.count{
return $0 < $1
}
return $0.characters.count < $1.characters.count
}
print(array)
5.补充
.数组的过滤,映射,缩减
let array = [37,23,49,93,54,81,29]
1.过滤
let newArray = array.filter {$0 > 50}
print(newArray)
let newArray1 = array.filter {$0 % 2 == 0}
print(newArray1)
2.映射
let newArray2 = array.map { $0 * $0}
print(newArray2)
let newArray5 = array.map{sqrt((Double)($0))}
print(newArray5)
3.缩减
let result1 = array.reduce(0, combine: +)
print(result1)
let result2 = array.reduce(1, combine: *)
print(result2)
let result3 = array.reduce(array[0]){
$1 > $0 ? $1 : $0
}
print(result3)
let strArray = ["I","love","you"]
let result4 = strArray.reduce(""){
$0 + " " + $1
}
print(result4)
四.面向对象
1.面向对象的几个步骤:
步骤一:定义类(如果你要用的类苹果都没有提供出来,就执行第二步)
//定义类就可以创建出新的类型
//学生类
class Student{ //首字母都要大写
//变量定义到类的外面就叫变量 - variable
//变量定义到类的里面就叫属性 - property
//数据抽象 - 找到和学生相关的属性(找名词)
var name: String
var age: Int
//初始化方法(构造方法/构造器) - 创建对象要使用的方法 - constructor
init(name: String,age: Int){
self.name = name
self.age = age
}
//行为抽象 - 找到和学生相关的方法(找动词)
func eat(foodName: String) -> Void{
print("\(name)正在吃饭.")
}
func study(courseName: String){
print("\(name)正在学习\(courseName).")
}
func watchJapaneseAV(){
if age >= 18{
print("\(name)正在观看岛国爱情动作片.")
}
else{
print("亲爱的\(name)快去看《熊出没》吧!")
}
}
}
//写到类里面的函数叫方法 - method,写到类的里面一般就叫函数 - function
步骤二:创建对象(调用初始化方法
let stu1 = Student(name: "王景亮", age: 25)
步骤三:给对象发消息(通过给对象那个发消息来解决问题)
stu1.eat("")
stu1.study("Swift程序设计")
stu1.watchJapaneseAV()
2.类的举例
//枚举类型:枚举是定义符号常量的最佳方式
符号常量总是优先于普通常量
enum Gender {
case Male,Female
}
class Dog {
var nickname : String
var sex: Gender
init(nickname: String, sex: Gender){
self.nickname = nickname
self.sex = sex
}
func bark(){
print("\(nickname): 汪汪汪。。")
}
func mate(other: Dog) -> Bool{
if sex != other.sex{
print("\(nickname)和\(other.nickname)正在交配。。。")
return true
}
else{
return false
}
}
}
let dog1 = Dog(nickname: "旺财", sex: .Male)
let dog2 = Dog(nickname: "大黄", sex: .Female)
dog1.bark()
dog2.bark()
if dog1.mate(dog2){
print("交配成功!")
}
else{
print("交配失败!")
}
3.一般我们把类写成一个文件,以便我们调用和管理
1.线的类:
class Line {
var start : Point
var end : Point
init(start:Point,end:Point){
self.start = start
self.end = end
}
func intersects(other: Line) ->Bool{
return false
}
var length : Double{
get {return start.distanceTo(end) }
}
}
2.三角形类:
class Triangle {
var va: Point
var vb: Point
var vc: Point
init(va:Point,vb:Point,vc:Point){
self.va = va
self.vb = vb
self.vc = vc
}
var perimeter : Double{
get {
let ab = va.distanceTo(vb)
let bc = vb.distanceTo(vc)
let ac = vc.distanceTo(va)
return ab + bc + ac
}
}
var area : Double{
get {
let ab = va.distanceTo(vb)
let bc = vb.distanceTo(vc)
let ac = vc.distanceTo(va)
let halfp = perimeter / 2
return sqrt(halfp * (halfp - ab) * (halfp - bc) * (halfp - ac))
}
}
}
3.点类
class Point {
var x: Double
var y: Double
//我们可以在一个类中定义多个初始化方法
convenience init(){
self.init(x : 0,y : 0)
}
//便利初始化方法/便利构造器
//调用了其他的初始化方法的初始化方法
convenience init(point:(Double,Double)){
self.init(x: point.0,y: point.1)
}
//指派构造器方法,指派构造器
//被其他初始化方法调用的初始化方法
init(x:Double,y:Double){
self.x = x
self.y = y
}
func moveTo(m: Double,n: Double){
self.x = m
self.y = n
}
func distanceTo(other: Point) -> Double{
let x1 = other.x - x
let y1 = other.y - y
return sqrt(x1 * x1 + y1 * y1)
}
}
4.计算属性与访问修饰符
-找名词和动词。名词会成为类或者类中的属性,动词会成为类中的方法
// 数据抽象
//行为抽象
// 初始化方法
//访问修饰符
//public (公开)
//internal(内部的) - 默认
//private (私有)
public class Circle {
//存储属性(保存和元相关的数据的属性)
var radius: Double
init(radius: Double){
self.radius = radius
}
//通常获得某个计算出的值得方法,通常都写成计算属性
//computational property
//计算属性(通过对存储属性做运算得到的属性)
var perimeter: Double {
//圆的周长是一个只读属性
//所以此处只有get{}没有set{}
get { return 2 * M_PI * radius }
}
var area : Double{
get { return M_PI * radius * radius }
}
}
5.重载运算符
有时在我们写程序过程中两个对象不能直接的做 + - * / % 等等的运算,我们需要将运算符根据我们的需要重载(其实这几种常用的运算符也是一种函数)
func <(one: Student,two: Student) -> Bool {
return one.age < two.age
}
//运算符的重载
let stuArray = [
Student(name: "wangjingliang", age: 21),
Student(name: "lee xiaolong", age: 49),
Student(name: "zhang nima", age: 18),
Student(name: "Guo jing", age: 26)
]
let newArray = stuArray.sort(<)
for stu in newArray{
print("\(stu.name): \(stu.age)")
}
五.继承和多肽
继承:主要是指,在父类存在的情况下,子类能够继承父类的相关属性。
父类:
enum Gender{
case Male
case Female
}
class Pet {
var nickname : String
var gender : Gender
var age : Int
init(nickname : String ,gender : Gender,age : Int){
self.nickname = nickname
self.gender = gender
self.age = age
}
func eat(){
print("\(nickname)正在吃吃吃")
}
func play(){
print("\(nickname)正在玩耍")
}
func shout(){
print("\(nickname)发出了叫声")
}
}
一个子类:
class Cat: Pet{
var hairColor: String?
override func shout() {
//override表示重写,父类有的方法子类可以重新实现这个过程叫方法的重写,需要在方法前添加override关键字,重写有时也被称为,置换,覆盖,覆写。。。。
print("\(nickname)正在喵喵喵。。。")
}
override func play() {
super.play() // 调用父类的方法
print("\(nickname)正在玩毛线")
}
func catchmouse(){
print("\(nickname)正在抓耗子")
}
}
第二个子类:
class Dog : Pet {
var isLarge : Bool
init(nickname: String,gender: Gender,age: Int,isLarge: Bool){
self.isLarge = isLarge
super.init(nickname: nickname, gender: gender, age: age)
}
override func shout() {
print("\(nickname)正在汪汪汪,,,")
}
override func play() {
print("\(nickname)正在玩球球")
}
override func eat() {
print("\(nickname)正在吃粑粑")
}
}
let petsArray = [
Cat(nickname:"加菲",gender: .Female, age:2),
Dog(nickname: "小王", gender: .Male, age: 3, isLarge: true),
Dog(nickname: "王景亮", gender: .Male, age: 5, isLarge: false),
Monkey(nickname: "小芳",gender: .Male, age: 10)
]
for pet in petsArray{
//pet.eat()
// pet.play()
// 同样的对象类型(Pet类型)接受相同的消息(调用相同的方法)
//但是做了不同的事情,这就是多肽(polymorphism)
// 1.方法的重写:子类在继承父类的过程中,对父类已有的方法进行重写,而且不同的子类给出不同的实现版本
//2.对象造型:将子类对象当成父类型来使用
//可以通过if+as?将父类型安全的转换成子类型然后再调用子类特有的方法
pet.shout()
if let dog = pet as? Dog{
dog.eat()
}
else if let cat = pet as? Cat{
cat.catchmouse()
}
}
六.总结
这是小编的swift学习的烧脑的第二周,总的来说还是收获颇多,第一次这么认真的学习一种编程语言,但是很多地方还是想不明白,我还会努力的,希望在接下来的日子里做得更好,如果你觉得以上内容对你有所帮助,不妨动一下您的贵手,
点一波关注,后面我还会继续写一些这方面的学习心得。有什么不足的地方,
欢迎指出,你们的建议将是对我最大的支持,谢谢!