Swift - 字符串 | 整型 | 浮点型
前言
Swift 中常用的数据类型有 Int、Float、Double、Bool、Character、String、Array、Dictionary、Tuple、Optional...... 数据类型的首字母都是大写
一般来说没有必要明确指定变量、常量的类型,Swift 可以自动推断出这个常量、变量的类型,如 let age = 20
正因为有类型推断的存在,Swift 和 C、OC 比起来很少需要声明数据类型
数据类型
1. 整型
整数分为两种类型:Swift 提供了 8、16、32、64 位的有符号和无符号整数,比如 UInt8、Int32
A 有符号:正、负、零
B 无符号:正、零
最值:可以通过 min/max 属性来获取某个类型的最小值和最大值
let minValue = UInt8.min // 0 let maxValue = UInt8.max // 255
Int | UInt
A Int、UInt 的长度与当前系统平台保持一致
B 在定义变量时别总是在考虑有无符号、数据长度的问题,尽量使用 Int,这样可以保证代码的简洁、可复用性
整数的表示形式
A 十进制数:没有前缀,如 17
1.25e2 表示 1.25 × 10^2
1.25e-2 表示 1.25 × 10^-2
B 二进制数:0b 为前缀,如 0b10001
C 八进制数:0o 为前缀,如 0o21
D 十六进制数:0x 为前缀且一定要有指数,如 0x11
0xFp2 表示 15 × 2^2 等于 60.0
0xFp-2 表示 15 × 2^-2 等于 3.75
0xFp0 表示 15 × 2^0 等于 15
2. 浮点型
Swift 提供了两种浮点数类型:Double/64 位 和 Float/32 位
A 精确程度:与 C语言 一样,Double 至少 15 位小数;Float 至少 6 位小数;默认 Double
B 表示形式:浮点数可以用十进制和十六进制两种进制来表示
数字格式:数字可以增加额外的格式,使它们更容易阅读
// 增加额外的零 0 let money1 = 001999 // 1999 let money2 = 001999.000 // 1999.0 // 增加额外的下划线 let oneMillion1 = 1_000_000 // 1000000 let overOneMillion = 1_000_000.000_001 // 1000000.000001
3. 类型转换
两个类型不同的数值,是不能够直接进行运算的
// 整数 var changeValue01 : Int8 = 100 var changeValue02 : Int64 = 300 var changeSum = changeValue01 + changeValue02 // 编译报错 var changeSum = Int64(changeValue01) + changeValue02 // 需转换后运算 // 实数 var changeValue11 : Double = 100 var changeValue12 : Float = 300.2 var changeSum10 = changeValue01 + changeValue02 // 编译报错 var changeSum10 = changeValue11 + Double(changeValue12)
4. 类型别名
使用 typealias 关键字来定义数据类型的别名,同 OC 的 typedef 相似
typealias kind01 = Int var w : kind01 = 64
5. 字符串
字符串是 String型 数据,用双引号包住文字内容。在 Swift 中字符串同样有可变字符串和不可变字符串类型之分,可变不可变取决于用 let 关键字还是 var 关键字
注:Swift 中的字符串是值类型,而 OC 中若字符串不加声明的话则是引用类型
如何使用字符串
A 字符串初始化
// 方式一: 空字面量 var emptyString = "" // 方式二: var anotherEmptyString = String() // 方式三 // 传递一个值是 Character型 的数组作为自变量来初始化 let catCharacters: [Character] = ["C", "a", "t", "!", "🐱"] print(catCharacters)// ["C", "a", "t", "!", "🐱"] var catString = String(catCharacters) print(catString) // Cat!🐱 // 判空 if anotherEmptyString.isEmpty { // 执行下行代码 print("Nothing to see") }
B 多行字符串
// 如果你需要一个字符串是跨越多行的,那就使用多行字符串字面量 // 它由一对三个双引号包裹着的具有固定顺序的文本字符集 // \ 续行符:要加在行尾,表示不换行 let quotation = """ The White Rabbit put on his spectacles. "Where shall I begin,please your Majesty?" he asked.\ "Begin at the beginning,"the King said gravely """ print(quotation) // 两者效果一样:单行 let singleLineString = "These are the same." let multilineString = """ These are the same. """ print(singleLineString) print(multilineString) // 多行字符串字面量能够缩进来匹配周围的代码:按格式输出 let quotations = """ i am white. you are black he is green " """ print(quotations)
// badStart 最后一行没有换行符,则它与 end 的第一行结合到了一起,共计两行 let badStart = """ one two """ let end = """ three """ print(badStart + end) print("\n") // goodStart 以换行符结尾,所以它与 end 拼接的字符串总共有三行 let goodStart = """ one two """ print(goodStart + end)
C 转义字符
// 转义字符:\0(空字符)、\\(反斜线)、\t(水平制表符)、\n(换行符)、\r(回车符)、\"(双引号)、\'(单引号) // 由于多行字符串字面量使用了三个双引号 // 所以在多行字符串字面量里可直接使用双引号(不需要加上转义符) let wiseWords = "\" Imagination is more important than knowledge \" - Einstein" print(wiseWords) // " Imagination is more important than knowledge " - Einstein // 在多行字符串字面量中使用 """ 的话,就需要使用至少一个转义符(\) let threeDoubleQuotesAAA = """ Escaping the first quote \""" """ print(threeDoubleQuotesAAA) // Escaping the first quote """ let threeDoubleQuotesBBB = """ Escaping the first quote \"\"\" """ print(threeDoubleQuotesBBB) // Escaping the first quote """ // threeDoubleQuotesAAA 和 threeDoubleQuotesBBB 效果一样
D Unicode 标量
// \u{n} 其中 n 为任意一到八位十六进制数且可用的 Unicode 位码 let demoA = "\u{2665}" print(demoA) // ♥ let demoB = "\u{2662}" print(demoB) // ♢
E 扩展字符串分隔符:将字符串放在引号中,并用数字符号 # 括起来
// 字符串中的特殊字符将会被直接包含输出而非转义后的效果 let description1 = #"Line 1 \n Line 2"# print(description1) print("\n") // 如果匹配转义字符时想要实现转义效果 // 则后面要添加与起始位置个数相匹配的 # let description2 = #"Line 1 \#n Line 2"# print(description2+"\n") // 不会自动换行 let description3 = ##"Line 3 \#nLine 4"## // \#n 中的 # 应是两个 print(description3+"\n")
F 索引
// 字符数量 let greeting = "Tag!" print(greeting.count)// 4 // 第一个/最后个的索引:如果是空串,那么 startIndex 和 endIndex 相等 print(greeting.startIndex) // Index(_rawBits: 1) print(greeting[greeting.startIndex])// T // 得到前面或后面的一个索引 print(greeting[greeting.index(before: greeting.endIndex)]) // ! print(greeting[greeting.index(after: greeting.startIndex)])// a // 获取对应偏移量的索引 let index = greeting.index(greeting.startIndex, offsetBy: 2) print(greeting[index]) // g // 不同的字符可能会占用不同数量的内存空间,所以 endIndex 属性不能作为一个字符串的有效下标 print(greeting.endIndex) // Index(_rawBits: 262151) // greeting[greeting.endIndex] // 运行crash:索引越界 // greeting.index(after: greeting.endIndex) // 同样是 error print("\n------for......in 循环-----\n") // 字符串不能用整数做索引:indices 会创建一个包含全部索引的范围,用来在一个字符串中访问单个字符 for indexDemo in greeting.indices { print("\(indexDemo) = \(greeting[indexDemo])") }
G 增、删、改
// append() 方法:将一个字符附加到一个字符串变量的尾部 var dogString = "123" let exMark: Character = "!" dogString.append(exMark) print(dogString)// 123! var dogC = "A" dogC.append(exMark) print(dogC)// A! // 切忌将一个字符串或者字符添加到一个已经存在的字符变量上,因为字符变量只能包含一个字符 // var dogD: Character = "!" // dogD.append(exMark) // 编译报错 //------------------------ // 插入 var welcome = "hello" welcome.insert("!", at: welcome.endIndex) print(welcome) // hello! welcome.insert(contentsOf: "here!", at: welcome.endIndex) print(welcome) // hello!here! // 插入内容 welcome.insert(contentsOf:" we go", at: welcome.index(before: welcome.endIndex)) print(welcome)// hello!here we go! //------------------------ // 删除 welcome.remove(at: welcome.index(before: welcome.endIndex)) // hello here print(welcome) // hello!here we go // 删除范围 let range = welcome.index(welcome.endIndex, offsetBy: -6) ..< welcome.endIndex welcome.removeSubrange(range)// hell print(welcome) // hello!here let greeting = "Hello,world!" let index = greeting.firstIndex(of: ",") ?? greeting.endIndex let beginning = greeting[..<index] print(beginning) // Hello
注:String 和 SubString 两者的区别在于性能优化上,如下
SubString 可以重用原 String 的内存空间,或者另一个 SubString 的内存空间;String 也有同样的优化,但如果两个 String 共享内存的话,它们就会相等。这意味着你在修改 String 和 SubString 之前都不需要消耗性能去复制内存
SubString 不适合长期存储,因为它重用了原 String 的内存空间,原 String 的内存空间必须保留直到它的 SubString 不再被使用为止,当你需要长时间保存结果时,就把 SubString 转化为 String 的实例
let someWord = "world!" let index = someWord.firstIndex(of: "r") ?? someWord.endIndex let newWord = someWord[..<index] print(newWord) // wo // 把结果转化为 String 以便长期存储 let newString = String(newWord)
H Swift 提供了三种方式来比较文本值:字符串字符相等、前缀相等、后缀相等。字符串或字符可用等于操作符 == 和不等于操作符 !=
let quotation = "We're a lot alike, you and Me." let sameQuotation = "We're a lot alike, you AND Me." if quotation == sameQuotation { print("These two strings are considered equal") }else{ print("different")// 执行该分支 }
注:Swift 和 OC 做了完美对接!它可以完全可以使用 NSString 方法
// 拼接 + var initString01 = "" initString01 += "21 class" print(initString01)// 21 class // 大小写转换 var changeString = "good boy" var changeStringUpper = changeString.uppercased() print(changeStringUpper) // GOOD BOY print(changeStringUpper.lowercased())// good boy // 插值:插值表达式不能包含非转义反斜杠 \ 并且不能包含回车或换行符 var insertNumber = 23 print("insertNumber = \(insertNumber)")// insertNumber = 23 // 截取 var cupStr : NSMutableString = "makeit,neccessary" print(cupStr.substring(from:3))// eit,neccessary // 删 var s01 = "Treat a man as he can" let index_i = s01.index(s01.startIndex, offsetBy: 9);// 从起始索引开始 9 个的字符长度 var s02 : String = s01.substring(from: index_i ) // 删除下标前的字符串 print(s02)// an as he can print("----------------------------------------") // hasPrefix(_:) 和 hasSuffix(_:) let romeoAndJuliet = [ "Act 1 Scene 1: Verona, A public place", "Act 1 Scene 2: Capulet's mansion", "Act 2 Scene 1: Outside Capulet's mansion", "Act 2 Scene 2: Capulet's orchard", "Act 2 Scene 3: Friar Lawrence's cell" ] var act1SceneCount = 0 for sce in romeoAndJuliet { if sce.hasPrefix("Act 1 ") { act1SceneCount += 1 } } print("There are \(act1SceneCount) scenes in Act 1") // There are 2 scenes in Act 1
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)