Swift-20-基础数据类型

数据定义

语法规则

先来看下下面的代码

import Cocoa

var num1 = "four" //a
var num2: String = "four" //b
var num3 = 4       //c
var num4: Int = 4  //d

上面的几行代码都能正常运行,其中a和b行等价,c和d行等价。区另就在于是否声明了类型,虽说swift会根据值的类型来推断其变量的类型,保证程序运行不会出现,但还是建议以b和d行的写法为准,因为可读性比较强也会避免很潜在的bug。

可简单理解为swift的类型是一种兼容弱和强类型的一种语法格式,在实际使用中强烈建议采用强类型来定义;

数据类型

在Swift中数据分为常量和变量两种,分别会使用不同的关键字来修饰:

  • var:用于定义变量,即值可被改变;
  • let:用于定义常量,即值一旦初始化后就不允许改变;
//用let定义常量,值不能被改变
let numberOfStoplights: Int = 4
let townName: String = "Londo"

//用var定义变量,值可以被改变
var population: Int = population = 5422

//采用\(varName)的方式来引用变量
let townDescription =
    "\(townName) has a population of \(population) and \(numberOfStoplights) stoplights."

//值打印到Console控制台上
print(townDescription)

代码注释

有两种注释方法:

  1. 单行注释://
  2. 多行注释:/* */或 /** /
//我是单行行注释,不能换行写哟

/**
如果有多行注释要写,可以用这种方式
 */

带标题的注释,用MARK:分隔,但只能用于行注释不能用于块注释

// MARK: Extend Velocity to suport converting
// I.e., there is a problem with the interchangeability of Velocity for Double

在这里插入图片描述

基础数据类型

Character

Swift 的字符是一个单一的字符字符串字面量,数据类型为 Character。

import Cocoa

let char1: Character = "A"
let char2: Character = "B"

print("char1 的值为 \(char1)")
print("char2 的值为 \(char2)")

//~~char1 的值为 A
//~~char2 的值为 B

Swift 中不能创建空的 Character(字符) 类型变量或常量:

import Cocoa

// Swift 中以下赋值会报错
let char1: Character = ""
var char2: Character = ""

print("char1 的值为 \(char1)")
print("char2 的值为 \(char2)")
//~~ error: cannot convert value of type 'String' to specified type 'Character'

布尔

布尔值字面量有三个值,它们是 Swift 的保留关键字:

  • true 表示真。
  • false 表示假。
  • nil 表示没有值。
let aBool = true        //布尔值字面量
let a:Bool = true

字符串

组成Swift字符串底层实现为集合形式,由多个Character类型的单个字符组成。

声明

在swift中字符串不分可变和不可变,可变的特性全部接由var和let来限定。

//以下两种声明方式是等价的
var errorString: String = "The request failed:"
var errorString = "Hello, playground"
var errorString += "!"

//计算长度
print(playground.count)

unicode声明,标准语法格式为: \u{}。值为十六进制的数。

let oneCoolDude = "\u{1F60E}"
let aAcute = "\u{0061}\u{0301}"

在这里插入图片描述

遍历

//逐个字母打印
let playground = "Hello, playground"
for scalar in playground.unicodeScalars {
    print("\(scalar) ")
    //print("\(scalar.description) ") //与上面代码等价
    //print("\(scalar.value) ")
}

在这里插入图片描述

索引与区间

这些方法比较特殊,需要额外记一下。

let playground = "Hello, playground"
let start = playground.startIndex
let end = playground.index(start, offsetBy: 4)
let fifthCharacter = playground[end]
let range = start...end
let firstFive = playground[range]

在这里插入图片描述

  • .startIndex:获取字符串的第一个索引,实际值是0;
  • .index(start, offsetBy: 4):取得从start往前数4个字符,即第5个字符,返回的一个索引值,实际值为5;
  • []:返回索引或索引区间指定的字符或字符串,此处返回hello中的o;最后一行代码返回的是hello;
  • range:表示区间,在本例中实际值为0~5;

下面是更复杂一点的区间的例子

let playground = "Hello, playground"
let start = playground.startIndex
let end = playground.index(start, offsetBy: 4)

let s1 = playground[start...] //Hello, playground
let s2 = playground[..<end] //Hell
let s3 = playground[start..<end] //Hell

整数

在Mac OS中,整形大小不固定,其会根据关键字来区分,比如在swift中整形可定义为:Int、Int8、Int16、Int32和Int64这几种,其中Int==Int64。

另外还有无符号数,UInt、UInt8、UInt16、UInt32和Int64这几种,即其值只能为正数。
在这里插入图片描述

var age: Int8 = 98

print("The maximum Int value is \(Int.max)")
print("The minimum Int value is \(Int.min)")
print("The maximum value for a 32-bit integer is \(Int32.max).")
print("The minimum value for a 32-bit integer is \(Int32.min).")

print("The maximum UInt value is \(UInt.max).")
print("The minimum UInt value is \(UInt.min).")

/*
The maximum Int value is 9223372036854775807
The minimum Int value is -9223372036854775808
The maximum value for a 32-bit integer is 2147483647.
The minimum value for a 32-bit integer is -2147483648.
The maximum UInt value is 18446744073709551615.
The minimum UInt value is 0.
*/

溢出操作

在swift中,整数都有一个范围,默认时就超出范围时就会报错,比如Int8最大值是-128~127之间,那么下面的代码就会有问题:

var overflow: Int8 = 120
overflow = overflow + 50

在这里插入图片描述

由于溢出中断了,如果想保证上面的程序能正常运行,则可以使用&关键字

var overflow: Int8 = 120
overflow = overflow &+ 8 //-128

注意这种溢出的值是从最小值折返着算,即Int8最大值为127,所以128会从最小值开始算为-128, 129则为-127。这一点比较有争议,但其实很多语言全是这样处理的。

这种溢出操作如无需要尽量不要使用,把所有的整数全定义为Int即可。

类型转换

在swift中不存在自动升级的情况,需要手工转换,比如下面的代码会出问题

var i16: Int16 = 32
var i8: Int8 = 2

var sum: Int16 = i16 + i8

可做如下修正

var i16: Int16 = 32
var i8: Int8 = 2

//只能类型相同
var sum: Int16 = i16 + Int16(i8)
//下面这行也会报错
var sum: Int32 = i16 + Int16(i8)

浮点数

在swift中有两种浮点数:Float表示32位,Double表示64位,区别在于精度高低。但同整数一样也会有Float32这样的类型。

let d2: Double = 1.1
let f1: Float = 100.3
print(10.0 + 11.4) //21.4
print(11.0 / 3.0) //3.6666666666666665,默认16位小数位
var d3: Double = d2 + Double(f1) //101.4000030517578

关于浮点数据的特殊说明:

  • 浮点数天生就是不精确的,所以不能用于科学计算;
  • 浮点数不能用==来比较;
  • 也会存在类型转换的问题;

精准度测试

let d11 = 1.1
let d22: Double = 1.1

if d11 == d22 { //TRUE,打印
    print("d1 and d2 are the same!")
}

print("d11 + 0.1 is \(d11 + 0.1)") //1.2000000000000002
if d11 + 0.1 == 1.2 { //FALSE,不会打印
    print("d1 plus 0.1 is equal to 1.2")
}

可空类型

可空类型(optional)是Swift的独特特性,用来指定某个实例可能没有值,如果一个实例没有值,也可称其为nil。任何类型都可以用可空类型来说明一个实例可能是nil,这和java的null有点类似。

本节主要讲述如何声明可空类型,如何使用可空实例绑定(optional binding)来检查某个可空实例是否为nil并且在有值的情况下使用其值,以及如何使用可空链式调用(optional chaining)来查询一连串可空值。

Swift为何要设计可空类型?Swift 设计可空类型的原因是为了处理缺失的值。在没有指定某个值可能为空的情况下,尝试访问这个值会导致运行时错误。通过使用可空类型(Optional),Swift 提供了一种安全的方式来处理可能缺失的值。可空类型在 Swift 中表现为一个抽象的类型 Optional,它有两个主要的类型 Optional.Some 和 Optional.None。当你声明一个变量为可空类型时,它可能包含一个具体的值,也可能为空(nil)。这样可以避免空指针异常等常见的运行时错误。确保了在编译时就能捕获潜在的空值问题,而不是等到运行时才崩溃。这有助于写出更加健壮和安全的代码。

例如,以下是一个可空类型的声明和使用

不可自动展开声明,关键字 ?

语法格式:var/let varName: varType? //关键字 ?


var errorCodeString: String?  //这行的值为nil

errorCodeString = "hello"    
print("\(errorCodeString)") //~~ Optional("404")

上面打印可空字符串时会在值外面套一个Optional("),现在可以用!来恢复正常输出,术语称为强制展开,强制展开会访问空实例封装的值。

var errorCodeString: String?
errorCodeString = "404"
print("\(errorCodeString)") //Optional("404")

if(errorCodeString != nil){
    print(errorCodeString!) //~~ 404
}

但需要注意,要强制展开一个空实例时,程序会出错异常,这也是上在的代码为何要加一个if的原因,比如下面这行代码就会报:Fatal error: Unexpectedly found nil while unwrapping an Optional value 异常。

var errorCodeString: String?
print("\(errorCodeString!)")

可自动展开声明,关键字 !

功能同用?声明的差不多,唯一的区别就是在展开时不需要写if判断语句了,其实的特性基本一样。

  • 在有值时,与?作用相同
var errorCodeString: String!
print(errorCodeString) //输出nil

errorCodeString = "404"
print(errorCodeString) //输出Optional("404")
print(errorCodeString!) //输出404

//下面这两行代码,在errorCodeString不等于nil时作用相同
let anotherErrorCodeString: String = errorCodeString! //404
let yetAnotherErrorCodeString = errorCodeString //404
  • 在值为nil时,则有一种写法就可以带来便利
var errorCodeString1: String!

let anotherErrorCodeString3 = errorCodeString1 //nil,正常
let anotherErrorCodeString4 = errorCodeString1!//异常

let anotherErrorCodeString1: String = errorCodeString1! //异常
let anotherErrorCodeString2: String = errorCodeString1 //异常

可空实例绑定

可空绑定,用于判断空实例用,如果非nil就将其赋给一个临时常量或变量,并且使这个常量或变量在条件语句的第一个分支代码中可用。

var errorCodeString: String?

//因为errorCodeString=nil所以此处不成立,不走print打印
if let theError = errorCodeString { 
    print("\(theError): \(errorCodeString)")
}

//这段代码和上面的代码等价
//if nil = errorCodeString {
//    let theError =errorCodeString
//    print("\(theError): \(theError)")
//}

//给theError赋值404,然后再进行运算,此处代码成立会打印print
errorCodeString = "404"
if let theError = errorCodeString { 
    if let errorCodeInteger = Int(theError) {
        print("\(theError): \(errorCodeInteger)")
    }
}

上面这种多个if的写法会比较麻烦,可以简写成以下的样子

var errorDescription: String?

if let theError = errorCodeString, let errorCodeInteger = Int(theError){
    print("\(theError): \(errorCodeInteger)")
}

可空链式调用

可空链式调用提供了一种对可空实例进行查询以判断其是否包含值的机制。与上面讲到的绑定相比,可空链式调用允许把多个查询串联为一个可空实例的值。即如果链式调用中的每个可空实例都包含值,那么每个调用都会成功,如果查询链中有一个可空实例为nil,那么整个链式调用就会返回nil。

看着挺复杂,其实就是方法调用

var errorCodeString: String!
errorCodeString = "404"

var errorDescription: String?

if let theError = errorCodeString, let errorCodeInteger = Int(theError), errorCodeInteger == 404 {
    errorDescription = "\(errorCodeInteger + 200): resource was not found."
}

//这处用.调用就是可空链式调用
var upCaseErrorDescription = errorDescription?.uppercased()
print(upCaseErrorDescription) //~~ Optional("604: RESOURCE WAS NOT FOUND.")

可空类型的值修改

术语称为原地修改,目的是避免创建新变量的麻烦,这种修改方式不受nil值的限制(仅限于?),在上面的示例代码中再添加几何观察下输出:

upCaseErrorDescription?.append(" PLEASE TRY AGAIN.")
//~~ Optional("604: RESOURCE WAS NOT FOUND. PLEASE TRY AGAIN.")
print(upCaseErrorDescription)


errorDescription = nil
let description = errorDescription ?? "No error"
//~~ No error
print(description)

可空类型运算

用??来实现便捷操作,相当于三元运算符,但??写法只能用于可空类型

var errorDescription: String?
let description = errorDescription ?? "No error" //No error

errorDescription = "500"
description = errorDescription ?? "No error" //500

//隐式展开可空类型,使用时一定不能为空,不然会报错
var test:String!
let aa:String? = nil //nil
var bb = aa ?? "hha" //hha

使用可空类型有几点需要注意的点:

  • ?号表示可空类型,等价于var errorCodeString: String? = nil,但不等价于var errorCodeString: String = nil,因为可空类型会有很多新特征可以使用;
  • 在?和!的取舍上尽量用?,只有在知道可空实例一定不会为nil或一旦为nil程序就会退出时才可以使用!。

print打印函数

标准结构如下所示:

print("The request failed")

var errorString: String = "The request failed"
print(errorString)

占位符

在拼装字符串时,可用占位符模式,语法格式:“\(varName) ”

let numberOfStoplights: Int = 4
var population: Int = 5422
let townName: String = "Londo"
let townDescription = "\(townName) has a population of \(population) and \(numberOfStoplights) stoplights."

//~~Londo has a population of 5422 and 4 stoplights.
print(townDescription)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/562690.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot集成Sleuth

引入Maven依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-sleuth</artifactId></dependency> 配置yml文件 bootstrap.yml文件增加如下配置 注&#xff1a;这个配置不是必须要&#…

嵌入式Linux开发实操(十七):Linux Media Infrastructure userspace API

视频和无线电流媒体设备使用的Linux内核到用户空间API,包括摄像机、模拟和数字电视接收卡、AM/FM接收卡、软件定义无线电(SDR)、流捕获和输出设备、编解码器设备和遥控器。典型的媒体设备硬件如下: 媒体基础设施API就是用于控制此类设备的,分五个部分。 第一部分V4L2 API…

Cpp_SDay03

何处染尘埃 文章目录 前言一、de bug二、disassembly&#xff08;代码变成汇编&#xff09;三、if loop总结 前言 重在坚持 一、de bug 消除bug&#xff08;debug&#xff09; ctrlaltm 再按1就调出了内存地址 可以在内存地址维度来看自己的赋值等 watch界面查看想查看的值 …

SpringCloud(二)

2.4、OpenFeign 请求需要的controller层代码实现跨项目的数据联调 OpenFeign是一个声明式的http客户端&#xff0c;是SpringCloud在Eureka公司开源的Feign基础上改造而来。官方地址: https:/lgithub.com/OpenFeign/feign 其作用就是基于SpringMVC的常见注解&#xff0c;帮我们优…

如何在本地创建一个新的Git仓库?

文章目录 **步骤一&#xff1a;开启项目之旅****步骤二&#xff1a;启动Git引擎****步骤三&#xff1a;验证仓库初始化情况****步骤四&#xff1a;填充项目内容****步骤五&#xff1a;保存更改——初次提交****&#xff08;可选步骤六&#xff1a;关联远程仓库并推送&#xff0…

还在找投稿邮箱?推荐一个靠谱的投稿平台给你

亲爱的朋友: 听说你还在为单位的信息宣传投稿考核而烦恼,四处寻找投稿邮箱,却屡屡碰壁,是吗?别着急,作为过来人,我想给你推荐一个靠谱的投稿平台——智慧软文发布系统网站。相信它能帮你轻松完成考核任务,让你的稿件更快更好地被媒体采纳。 想当年,我也曾像你一样,为了完成单…

分析和比较深度学习框架 PyTorch 和 Tensorflow

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 深度学习作为人工智能的一个重要分支&#xff0c;在过去十年中取得了显著的进展。PyTorch 和 TensorFlow 是目前最受欢迎、最强大的两个深度学习框架&#xff0c;它们各自拥有独特的特点和优势。 1. Py…

2024HW ---->内网横向移动

在蓝队的面试过程中&#xff0c;如果你会内网渗透的话&#xff0c;那是肯定的一个加分选项&#xff01;&#xff01;&#xff01; 那么从今天开始&#xff0c;我们就来讲一下内网的横向移动&#xff01;&#xff01;&#xff01; 目录 1.域内任意用户枚举 2.Password-Sprayi…

node的事件循环

异步同步啥的就不多说了&#xff0c;直接看node中有哪些是异步 其中灰色部分和操作系统有很大的关系&#xff0c;就不多说了&#xff0c;其中定时器属于timers队列&#xff0c;I/O操作属于poll队列&#xff0c;setImmediate属于check队列&#xff0c;其中nextTick和promise不属…

mklink 命令的使用(适用场景:C盘爆满,转移到其他盘)

一、背景 将Oracle数据库安装在D盘&#xff0c;由于磁盘爆满&#xff0c;需要将数据库转移到其他磁盘&#xff08;如&#xff1a;J盘&#xff09;。 在移动数据库之后&#xff0c;会出现数据库无法使用的情况&#xff0c;这时该如何解决&#xff1f;经了解&#xff0c;可以使用…

MariaDB InnoDB 空洞清理

1、背景 数据库占用服务器内存越来越高&#xff0c;除了bin-log文件之外&#xff0c;还发现了一些带有text或者longtext数据类型字段的表&#xff0c;这种表也会占用很高的服务器磁盘空间 数据库版本&#xff1a; 表引擎&#xff1a; InnoDB 数据量&#xff1a;清理之前1500万…

Xavier 初始化

Xavier 初始化 为什么在 W [ l ] n p . r a n d o m . r a n d n ( s h a p e ) n p . s q r t ( 1 n [ l − 1 ] ) W^{[l]}np.random.randn(shape)\times np.sqrt(\frac{1}{n^{[l-1]}}) W[l]np.random.randn(shape)np.sqrt(n[l−1]1​) 中需要乘以 n p . s q r t ( 1 n […

Linux服务器运维工具箱 监控管理建站一个脚本全搞定!

Linux服务器运维工具箱 监控管理建站一个脚本全搞定&#xff01; 一款全能脚本工具箱&#xff0c;使用shell脚本编写。专为Linux服务器监控、测试和管理而设计。无论您是初学者还是经验丰富的用户&#xff0c;该工具都能为您提供便捷的解决方案。集成了独创的Docker管理功能&a…

IDEA2024配置RunDashBoard(Services)面板

IDEA2024配置RunDashBoard(Services)面板 新版本的IDEA没有RunDashBoard&#xff0c;取而代之的是Services面板&#xff0c;不需要配置workspace.xml文件; 本文教你简单的方法就能一个SpringBoot的Main运行多次&#xff0c;方便调试。 1、配置启动类 导航栏&#xff0c;Edit…

sso-oauth2单点登录功能笔记

场景&#xff1a;最近公司2个系统需要做单点登录&#xff0c;A系统作为服务器&#xff0c;认证方式是sso-oauth2方式&#xff0c;B系统作为客户端&#xff0c;token方式是ta-token&#xff0c;先来张sso-oauth2认证方式的图 前置准备工作 第一步&#xff1a;要确认谁是服务提…

AI+PS快捷键大全!

hello&#xff0c;我是小索奇&#xff0c; 你会用Photoshop&#xff08;PS&#xff09;或者&#xff08;Illustrator&#xff09;AI吗&#xff1f;相信很多人都会接触到吧&#xff0c;但有一部分人很少用快捷键&#xff0c;仅凭借鼠标点击来实现功能&#xff0c;殊不知快捷键能…

spring版本介绍

Spring Framework 是一个广泛使用的 Java 平台&#xff0c;用于构建企业级应用程序。它提供了一个全面的编程和配置模型&#xff0c;支持现代 Java 应用程序的最佳实践&#xff0c;如依赖注入、面向切面编程以及基于注解的编程模型。自从 Spring 1.0 发布以来&#xff0c;已经经…

llama2 与 llama3比较

Llama 3 刚刚在4月18号推出&#xff0c;距 Llama 2 发布正好 9 个月。它已经可以在 Meta 网站上进行聊天&#xff0c;可以从 Huggingface 以 safetensors 或 GGUF 格式下载。 llama 2 与 llama3 比较 1. 模型输出&#xff08;model output&#xff09; llama 2 输出只能是文本…

Go诊断工具

Go 提供了一些出色的诊断工具,可帮助我们深入了解应用程序的执行情况。 1. 分析工具 分析工具可观测应用程序执行的各种指标。它使我们能够解决性能问题、检测争用、定位内存泄漏等。这些指标可以通过以下几个配置文件收集: CPU--确定应用程序将时间花在了哪里Goroutine--报…

【MySQL】查询(进阶)

文章目录 前言1、新增2、聚合查询2.1聚合函数2.1.1count2.1.2sum2.1.3avg2.1.4max和min 2.2、GROUP BY子句2.3HAVING 3、联合查询/多表查询3.1内连接和外连接3.2自连接3.3子查询3.4合并查询 前言 在前面的内容中我们已经把查询的基本操作介绍的差不多了&#xff0c;接下来我们…