swift string转int_Swift进阶二:基本数据类型相关
变量和常量
Swift中,使用关键字let来声明常量,使用关键字var来声明变量。
而在Objective-C中,如果没有特殊的指明,我们所声明的都是变量。可以通过如下几种方式来声明常量:
使用宏定义来模拟常量来使用。
使用const关键字来声明类型常量。
声明readonly只读属性。但是这只是一种伪常量,因为我们可以在其子类中通过复写getter方法来修改其值。
数值类型
整型
有符号整型
Int8:有符号8位整型,1字节
Int16:有符号16位整型,2字节
Int32:有符号32位整型,4字节
Int64:有符号64位整型,8字节
Int:默认,和平台相关(拥有与当前平台的原生字相同的长度),相当于OC中的NSInteger。
无符号整型
UInt8:无符号8位整型,1字节
UInt16:无符号16位整型,2字节
UInt32:无符号32位整型,4字节
UInt64:无符号64位整型,8字节
UInt:默认,和平台相关(拥有与当前平台的原生字相同的长度),相当于OC中的NSUInteger
浮点型
Float:32位浮点型,,4字节,至少有6位数字的精度
Double:64位浮点型(默认),8字节,至少有15位数字的精度
鉴于Double的精度更高,所以在二者均可的情况下,优先使用Double类型。
各个类型的取值区间如下:
类型别名
类型别名是一个为已存在类型定义的一个可选择的名字,可以使用typealias关键字来定义一个类型的别名。
有的时候,一个既有类型的名字可能会比较晦涩,在某些业务场景下,联系上下文,如果你想使用一个更合适、更具有表达性的名字来代替这个晦涩的既有类型名,那么就可以使用别名。
比如说,在做音频编码的时候,音频的采样率就是一个8位无符号整数,此时就可以给UInt8起一个别名:
typealias AudioSample = UInt8let sample: AudioSample = 32
Optional可选型
可选型的使用:
let str: String? = "norman"//判断展开if str != nil { let count = str!.count print(count) // 6}//可选绑定if let actualStr = str { let count = actualStr.count print(count) // 6}//强制展开//⚠️使用!进行强制展开之前必须确保可选项中包含一个非nil的值//let count = str!.count//print(count) // 6//隐式展开//⚠️有些可选项一旦被设定值之后,就会一直拥有值,此时就不必每次访问的时候都进行展开//通过在声明的类型后面添加一个叹号来隐式展开可选项let string: String! = "lavie"print(string.count) // 5//可选链//⚠️使用可选链的返回结果也是一个可选项let count = str?.countif let count = count { print(count) // 6}
可选型Optional的实现原理探究
Optional实际上是标准库里面的一个enum类型,Optional在标准库中的定义如下:
public enum Optional<Wrapped> : ExpressibleByNilLiteral { /// The absence of a value. /// /// In code, the absence of a value is typically written using the `nil` /// literal rather than the explicit `.none` enumeration case. case none /// The presence of a value, stored as `Wrapped`. case some(Wrapped) /// Creates an instance that stores the given value. public init(_ some: Wrapped) @inlinable public func map(_ transform: (Wrapped) throws -> U) rethrows -> U? @inlinable public func flatMap(_ transform: (Wrapped) throws -> U?) rethrows -> U? public init(nilLiteral: ()) @inlinable public var unsafelyUnwrapped: Wrapped { get } public static func ~= (lhs: _OptionalNilComparisonType, rhs: Wrapped?) -> Bool public static func == (lhs: Wrapped?, rhs: _OptionalNilComparisonType) -> Bool public static func != (lhs: Wrapped?, rhs: _OptionalNilComparisonType) -> Bool public static func == (lhs: _OptionalNilComparisonType, rhs: Wrapped?) -> Bool public static func != (lhs: _OptionalNilComparisonType, rhs: Wrapped?) -> Bool}
通过上面的定义我们可知,Optional是一个enum,它有两个值:none和some,其中some是泛型的(使用Wrapped来表示泛型)。
Optional.none就是nil;
Optional.some则包装了实际的值。
在枚举Optional中,还有一个泛型属性unsafelyUnwrapped,其定义如下:
@inlinable public var unsafelyUnwrapped: Wrapped { get }
理论上,我们可以直接调用unsafelyUnwrapped属性来获取可选项的值:
let str: String? = "norman"if str != nil { print(str.unsafelyUnwrapped.count)}
实际上,str.unsafelyUnwrapped等同于str!。
字符串相关
Raw String中的字符串插值
let sum = 3 + 4let result1 = "sum is \(sum)" // sum is 7let result2 = #"sum is \(sum)"# // sum is \\(sum)let result3 = #"sum is \#(sum)"# // sum is 7
使用索引访问和修改字符串
每一个String值都有相关的索引类型String.Index,它用于表示每个Character在字符串中的位置。
startIndex属性表示String中第一个Character的位置;endIndex表示String中最后一个字符后面的那个位置。
endIndex属性并不是字符串下标脚本的合法实际参数。
如果String为空,则String和endIndex相等。
String.Index的定义如下:
/// A position of a character or code unit in a string. public struct Index { }
我们可以看到,Index实际上是一个结构体。
我们可以使用index(before:)和index(after:)方法来访问给定索引的前后;
要访问给定索引更远的索引,你可以使用index(_, offsetBy:);
let name = "norman" print(name[name.startIndex]) // n print(name[name.index(before: name.endIndex)]) // n print(name[name.index(after: name.startIndex)]) // 0 let index = name.index(name.startIndex, offsetBy: 3) print(name[index]) // m
可以使用insert来插入字符或者字符串:
var name = "norman" //插入字符 name.insert("~", at: name.endIndex) print(name) // norman~ //插入字符串 name.insert(contentsOf: "Hello, ", at: name.startIndex) print(name) // Hello, norman~
可以使用remove和removeSubrange方法移除字符或者字符串:
var name = "Hello, norman~" //移除字符 name.remove(at: name.index(before: name.endIndex)) print(name) //移除字符串 let range = name.startIndex...name.index(name.startIndex, offsetBy: 5) name.removeSubrange(range) print(name)
为什么Swift字符串的索引是String.Index结构体,而不是数字下标
在Unicode中, 一个我们可以看得见的单一字符,有可能并不是一个Unicdoe标量。例如【é】这个字符。它可以是一个Unicode标量【\u{e9}】, 也有可能是二个Unicode标量【\u{65}】和【\u{301}】组合的结果。上述2个标量的情况在Swift计算中,仍然会被认为是1个字符。我们可以认为Swift中的charactor类型是一种扩展的类型。其由1个或者多个Unicode标量组成。不再是我们认为的1对1的对应关系。character是一个Unicode标量序列。正因如此。一个字符串的长度,或者随机访问,需要遍历这个字符串的char序列进行Combine计算后才能得到。所以Swift用String.Index这个结构体来抽象String中的char的index。Swift也就不能提供下标为数字的随机访问。而且仅提供Start和End2个默认的String.index。这是因为它只能告诉你最开始的和最后的, 因为其他的都需要去从前或者从后进行遍历。在需要的时候进行Unicode变量组合计算后才能真正获知。那有没有方法使用数字字面量来进行切片呢?答案是可以的。如下:extension String { public subscript(intRange: Range) -> String { let start = self.index(startIndex, offsetBy: intRange.startIndex) let end = self.index(startIndex, offsetBy: intRange.endIndex) let range = start.. return String(self[range]) }} 我们使用扩展。来扩展String 类型的一个下标操作。传入的Range是Int类型的。
子字符串——Substring
Swift中的子字符串的概念和Objective-C中子字符串的概念相当不同。
Swift中,使用下标或者类似prefix等方法得到的子字符串是Substring类型。Substring拥有String的大部分方法。Substring也可以转成String。
而Objective-C中,无论是原字符串还是原字符串的子字符串,都是NSString类型。
let greeting = "hello, swift" let endIndex = greeting.index(greeting.startIndex, offsetBy: 4) ?? greeting.endIndex let begining = greeting[...endIndex] // Substring let newString = String(begining) // 将Substring转成String print(newString) // hello
下面我们来简单介绍下Swift中的Substring。
Swift中为什么要单独拉一个SubString出来呢?很大程度上是出于性能的考量。
在Swift中,子字符串会重用一部分原字符串的内存。如上图,子字符串“Hello”所指向的内存地址,还是原字符串“Hello,world!”的内存中存储“Hello”的那部分内存地址。
我们在修改原始字符串,或者修改子字符串之前,都是不需要花费拷贝内存的代价的。但是一旦修改了一旦修改了原字符串,或者修改子字符串,或者要将子字符串转成String类型,那么子字符串就会单独拷贝出来,在新的内存区域存储该子字符串的内容。
String和Substring都会遵循StringProtocol协议。如果我们在平时的工作中需要定义一些字符串操作函数,那么所接受的参数优先遵循StringProtocol协议,而不是继承自String,这样就能够很方便地兼容所有类型的字符串。
以上。
对线上代码一定要有敬畏感,不随意改动或者删除任何一句线上代码。如果需要改动,比如将老接口替换成新接口,那么一定要将影响点详尽罗列出,并跟新老接口的后端负责人、其他使用该接口的前端客户端,产品等确认好,改好之后还要同步到测试,一定要做全量回归。千万不要觉得没问题就改了,一定要养成严谨的工作习惯。
swift string转int_Swift进阶二:基本数据类型相关相关推荐
- swift string转int_swift中结构体和类的区别(值类型和引用类型的区别)
在swift中结构体和类有着更多的相同之处,在一般的使用中能够做到互相替换.我们可以先看看官方文档的描述: Unlike other programming languages, Swift does ...
- 初探swift语言的学习笔记一(基本数据类型)
作者:fengsh998 原文地址:http://blog.csdn.net/fengsh998/article/details/28258805 转载请注明出处 如果觉得文章对你有所帮助,请通过留言 ...
- iOS开发Swift篇—(三)字符串和数据类型
一.字符串 字符串是String类型的数据,用双引号""包住文字内容 let website = "http://www.github.com" 1.字符串的 ...
- hive 强转为string_Hive(二)【数据类型、类型转换】
一.基本数据类型 HIVE MySQL JAVA 长度 例子 TINYINT TINYINT byte 1byte有符号整数 2 SMALINT SMALINT short 2byte有符号整数 20 ...
- Redis数据库(二)——数据类型
Redis数据库(二)--数据类型 一.String数据类型 1.set / get / append / strlen 2.incr / decr / incrby / decrby 3.getse ...
- Hive(二)——数据类型与文件格式
Hive(二)--数据类型与文件格式 数据 基本数据类型 集合数据类型 分隔符 # 数据: John Doe^A100000.0^AMary Smith^BTodd Jones^AFederal Ta ...
- 【Ardunio】开发入门教程【二】数据类型
Ardunio数据类型 boolean 布尔 char 字符 byte 字节 int 整数 unsigned int 无符号整数 long 长整数 unsigned long 无符号长整数 float ...
- python爬虫进阶案例,Python进阶(二十)-Python爬虫实例讲解
#Python进阶(二十)-Python爬虫实例讲解 本篇博文主要讲解Python爬虫实例,重点包括爬虫技术架构,组成爬虫的关键模块:URL管理器.HTML下载器和HTML解析器. ##爬虫简单架构 ...
- JavaScript进阶(二)
JavaScript进阶(二) 2019版黑马程序员javaScript进阶面向对象ES6 122集教程,哔哩哔哩链接:https://www.bilibili.com/video/BV1Kt411w ...
最新文章
- python redis链接建立实现分析
- linux gcc-9.2.0 源码编译
- 手握2.2亿美元,但想不起密码,还有两次机会,一起支支招啊!
- IE常见的CSS的BUG(一)
- oracle怎么设置sql每隔一段时间执行一次_Oracle大规模数据快速导出文本文件
- k8s集群dns问题解决办法
- 手机号脱敏处理_C#简单代码实现对手机号邮箱等隐私信息进行*号打码
- 高并发第一弹:准备阶段 了解高并发
- oracle 分区字符转换,Oracle 普通表与分区表转换
- java 异常 return_Java异常处理中同时有finally和return语句的执行问题
- 分布式文件系统FastDFS设计原理
- 【Office Word】论文排版有关技巧
- python信号处理教程_PhysioNet生理信号处理(五)--WFDB for Python(DEMO)
- 安全还是效率? 移动化的两难抉择
- java课程设计模拟画图_课程设计java画板模拟画图工具
- Spring源码之bean的实例化createBeanInstance方法解读
- Mintec.MineSight.3D.v7.0.3
- python在电力系统中的应用_PyPSA在电力系统潮流计算中的应用
- Linux+Nginx+SpringBoot+War环境下websocket部署遇到的问题
- 情景分析是什么?我们该如何去理解这个概念?
热门文章
- 2007图灵奖得主离开了:模型检测先驱Edmund Clarke因新冠逝世
- 35 w年薪,入职CV算法岗,我一个双非本科生如何做到的?
- Linux内核网络栈1.2.13-有关tcp/ip协议的基础入门
- 循环神经网络实现文本情感分类之使用LSTM完成文本情感分类
- 开发系统平台常用的-MVC设计模式简介
- 计算机的学生该怎么做?
- 网络工程师_记录的一些真题_2018上半年上午
- 解决Python通过pip安装报错:(有图)Could not install packages due to an EnvironmentError: HTTPSConnectionPool
- 基于相交线的双目平面SLAM
- 可复现的图像降噪算法总结——超赞整理