变量和常量

Swift中,使用关键字let来声明常量,使用关键字var来声明变量

在Objective-C中,如果没有特殊的指明,我们所声明的都是变量。可以通过如下几种方式来声明常量:

  1. 使用宏定义来模拟常量来使用。

  2. 使用const关键字来声明类型常量。

  3. 声明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进阶二:基本数据类型相关相关推荐

  1. swift string转int_swift中结构体和类的区别(值类型和引用类型的区别)

    在swift中结构体和类有着更多的相同之处,在一般的使用中能够做到互相替换.我们可以先看看官方文档的描述: Unlike other programming languages, Swift does ...

  2. 初探swift语言的学习笔记一(基本数据类型)

    作者:fengsh998 原文地址:http://blog.csdn.net/fengsh998/article/details/28258805 转载请注明出处 如果觉得文章对你有所帮助,请通过留言 ...

  3. iOS开发Swift篇—(三)字符串和数据类型

    一.字符串 字符串是String类型的数据,用双引号""包住文字内容  let website = "http://www.github.com" 1.字符串的 ...

  4. hive 强转为string_Hive(二)【数据类型、类型转换】

    一.基本数据类型 HIVE MySQL JAVA 长度 例子 TINYINT TINYINT byte 1byte有符号整数 2 SMALINT SMALINT short 2byte有符号整数 20 ...

  5. Redis数据库(二)——数据类型

    Redis数据库(二)--数据类型 一.String数据类型 1.set / get / append / strlen 2.incr / decr / incrby / decrby 3.getse ...

  6. Hive(二)——数据类型与文件格式

    Hive(二)--数据类型与文件格式 数据 基本数据类型 集合数据类型 分隔符 # 数据: John Doe^A100000.0^AMary Smith^BTodd Jones^AFederal Ta ...

  7. 【Ardunio】开发入门教程【二】数据类型

    Ardunio数据类型 boolean 布尔 char 字符 byte 字节 int 整数 unsigned int 无符号整数 long 长整数 unsigned long 无符号长整数 float ...

  8. python爬虫进阶案例,Python进阶(二十)-Python爬虫实例讲解

    #Python进阶(二十)-Python爬虫实例讲解 本篇博文主要讲解Python爬虫实例,重点包括爬虫技术架构,组成爬虫的关键模块:URL管理器.HTML下载器和HTML解析器. ##爬虫简单架构 ...

  9. JavaScript进阶(二)

    JavaScript进阶(二) 2019版黑马程序员javaScript进阶面向对象ES6 122集教程,哔哩哔哩链接:https://www.bilibili.com/video/BV1Kt411w ...

最新文章

  1. python redis链接建立实现分析
  2. linux gcc-9.2.0 源码编译
  3. 手握2.2亿美元,但想不起密码,还有两次机会,一起支支招啊!
  4. IE常见的CSS的BUG(一)
  5. oracle怎么设置sql每隔一段时间执行一次_Oracle大规模数据快速导出文本文件
  6. k8s集群dns问题解决办法
  7. 手机号脱敏处理_C#简单代码实现对手机号邮箱等隐私信息进行*号打码
  8. 高并发第一弹:准备阶段 了解高并发
  9. oracle 分区字符转换,Oracle 普通表与分区表转换
  10. java 异常 return_Java异常处理中同时有finally和return语句的执行问题
  11. 分布式文件系统FastDFS设计原理
  12. 【Office Word】论文排版有关技巧
  13. python信号处理教程_PhysioNet生理信号处理(五)--WFDB for Python(DEMO)
  14. 安全还是效率? 移动化的两难抉择
  15. java课程设计模拟画图_课程设计java画板模拟画图工具
  16. Spring源码之bean的实例化createBeanInstance方法解读
  17. Mintec.MineSight.3D.v7.0.3
  18. python在电力系统中的应用_PyPSA在电力系统潮流计算中的应用
  19. Linux+Nginx+SpringBoot+War环境下websocket部署遇到的问题
  20. 情景分析是什么?我们该如何去理解这个概念?

热门文章

  1. 2007图灵奖得主离开了:模型检测先驱Edmund Clarke因新冠逝世
  2. 35 w年薪,入职CV算法岗,我一个双非本科生如何做到的?
  3. Linux内核网络栈1.2.13-有关tcp/ip协议的基础入门
  4. 循环神经网络实现文本情感分类之使用LSTM完成文本情感分类
  5. 开发系统平台常用的-MVC设计模式简介
  6. 计算机的学生该怎么做?
  7. 网络工程师_记录的一些真题_2018上半年上午
  8. 解决Python通过pip安装报错:(有图)Could not install packages due to an EnvironmentError: HTTPSConnectionPool
  9. 基于相交线的双目平面SLAM
  10. 可复现的图像降噪算法总结——超赞整理