Swift-20-基础数据类型

news2025/1/10 11:56:06

数据定义

语法规则

先来看下下面的代码

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)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

docker-compose 安装MongoDB续:创建用户及赋权

文章目录 1. 问题描述2. 分析2.1 admin2.2 config2.3 local 3. 如何连接3.解决 1. 问题描述 在这一篇使用docker-compose创建MongoDB环境的笔记里&#xff0c;我们创建了数据库&#xff0c;但是似乎没有办法使用如Robo 3T这样的工具去连接数据库。连接的时候会返回这样的错误&…

关系抽取与属性补全

文章目录 实体关系抽取的任务定义机器学习框架属性补全 实体关系抽取的任务定义 从文本中抽取出两个或者多个实体之间的语义关系&#xff1b;从文本获取知识图谱三元组的主要技术手段&#xff0c;通常被用于知识图谱的补全。美丽的西湖坐落于浙江省的省会城市杭州的西南面。&am…

IDEA中SVN 的使用

文章目录 前言一、svn安装二、IDEA集成SVN总结 前言 svn可以老牌的代码仓库了 说实话svn还是和git无法相比的,毕竟git有本地仓库的概念,可以很好的处理冲突,然而svn是没有本地仓库的概念的,所以只能拉取别人的代码,然后处理冲突后,才能提交代码; 由于最近的工作换成了用svn仓…

el-menu 有一级二级三级菜单

效果如下 菜单代码如下 <el-menu:default-active"menuDefaultActive"class"el-menu-box":text-color"menuTextColor":active-text-color"menuActiveTextColor":unique-opened"true"><!-- 一级菜单 --><tem…

线程池的核心参数有哪些???

线程池的核心参数包括以下七个&#xff1a; corePoolSize&#xff1a; 这是线程池中的核心线程数&#xff0c;即池中会保留的最少线程数。当提交任务时&#xff0c;如果当前线程数小于核心线程数&#xff0c;线程池会创建新的线程来执行任务。如果当前线程数等于或大于核心线程…

Docker - 简介

原文地址&#xff0c;使用效果更佳&#xff01; Docker - 简介 | CoderMast编程桅杆https://www.codermast.com/dev-tools/docker/docker-introduce.html Docker是什么&#xff1f; Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从 Apache2.0 协议开源。 D…

css-Echarts图表初始显示异常非完全显示

1.echarts图表初始加载异常 2.问题原因 初次加载时&#xff0c;由于外层使用%比 echarts dom元素没有完全加载完成&#xff0c;canvas绘画继承本身宽高&#xff0c;造成Echarts图表初始显示异常非完全显示。 3.使用echarts图表可参考以下代码&#xff08;实现一定的自适应&am…

stm32开发之threadx+emwin+awizard使用记录

前言 图形化开发界面选择(awizard)emwin使用的版本是6.10芯片采用的是stm32f407zgt6这里使用的开发板是普中麒麟f4系列的 lcd驱动文件&#xff08;基于提供的源码修改&#xff09; 1、这里是剔除了很多兼容其他显示屏部分的代码&#xff0c;只保留具体信号的代码,把一些全局…

Java实现AVL树

AVI树 如果一颗二叉搜索树不平衡,那么搜索效率会受影响 二叉搜索树如果不是这种不平衡的情况,时间复杂度可以达到O(logn) 但是像图中的这种不平衡情况时间复杂度为O(n),那么如何解决呢? 可以通过旋转解决 旋转之后并不会破坏二叉搜索树的特性 判断是否平衡有一个规则:如果一…

如何进行景气分析

景气分析是一种短期经济分析方法。主要分析短时间内&#xff08;一般指一年内&#xff0c; 或几个月内&#xff09;经济运行的态势&#xff0c;包括当前的状态和未来的趋势。景气分析可以为宏观经济政策提供重要的决策与参考信息&#xff0c;例如根据经济运行的方向、强弱可建议…

【AI开发:音频】二、GPT-SoVITS使用方法和过程中出现的问题(GPU版)

1.FileNotFoundError: [Errno 2] No such file or directory: logs/guanshenxxx/2-name2text-0.txt 这个问题中包含了两个&#xff1a; 第一个&#xff1a;No module named pyopenjtalk 我的电脑出现的就是这个 解决&#xff1a;pip install pyopenjtalk 第二个&#xff1a…

数据结构练习-数据结构概述

----------------------------------------------------------------------------------------------------------------------------- 1. 在数据结构中&#xff0c;从逻辑上可以把数据结构分成( )。 A. 动态结构和静态结构 B. 紧凑结构和非紧凑结构 C. 线性结…

初识ansible变量及实例配置

目录 1、为什么要使用变量 2、变量分类 3、 变量详解 3.1 vars,vars_files , group_vars 3.1 .1 vars 剧本中定义变量 3.1.2 vars_file 将变量存放到一个文件中&#xff0c;并在剧本中引用 3.1.3 group_vars 创建一个变量文件给某个组使用 实例1-根据不同的主机…

CGLIB动态代理

文章目录 前言概要SpringBoot中使用小结 前言 当我们需要在Java中实现动态代理时&#xff0c;通常会考虑使用 JDK原生动态代理 或者 CGLIB动态代理。 我这里说一下CGLIB动态代理&#xff0c;并给出一个例子。 概要 CGLIB&#xff08;Code Generation Library&#xff09;是一…

无损以太网的ROCE革命,队列的缓存空间优化分析

ROCE无损以太网&#xff0c;队列的缓存空间优化 多级缓存架构优化芯片性能&#xff1a;* 缓存空间细分为芯片级、端口级和队列级&#xff0c;实现精细管理。* 无损队列引入Headroom缓存空间&#xff0c;确保数据完整性。 在芯片层面&#xff1a; 静态缓存为端口提供保证的缓存空…

RHCE:网络服务综合项目

基础配置&#xff1a; 1.配置主机名&#xff0c;静态IP地址 2.开启防火墙并配置 3.部分开启SElinux并配置 4.服务器之间使用同ntp.aliyun.com进行时间同步 5.服务器之间实现SSH免密登录 业务需求&#xff1a; 1.Server-NFS-DNS主机配置NFS服务器&#xff0c;将博客网…

智慧园区引领未来产业趋势:科技创新驱动园区发展,构建智慧化产业新体系

目录 一、引言 二、智慧园区引领未来产业趋势 1、产业集聚与协同发展 2、智能化生产与服务 3、绿色可持续发展 三、科技创新驱动园区发展 1、创新资源的集聚与整合 2、创新成果的转化与应用 3、创新文化的培育与弘扬 四、构建智慧化产业新体系 1、优化产业布局与结构…

5.SpringBoot 配置文件

文章目录 1.配置文件作用2.配置文件格式2.1项目中同时存在两种配置文件2.2application.properties2.2.1 application.properties语法格式2.2.2获取自定义配置项 2.3 application.yml2.3.1 application.yml语法格式2.3.1.1单双引号区别2.3.1.2和application.properties格式对比&…

安全狗云眼的主要功能有哪些?

"安全狗云眼"是一款综合性的网络安全产品&#xff0c;主要用于实时监控和保护企业的网络安全。其核心功能包括威胁检测、漏洞扫描、日志管理和合规性检查等。 以下是安全狗云眼的主要功能详细介绍&#xff1a; 1、资产管理 定期获取并记录主机上的Web站点、Web容器、…

Python连接Oracle数据库问题解决及Linux服务器操作知识

背景说明 最近在做一个视频分析的项目&#xff0c;然后需要将视频分析的数据写入到oracle数据库&#xff0c;直接在服务器上测试数据库连接的时候出现了这个bug提示&#xff0c;自己通过不断的研究探讨&#xff0c;最终把这个问题成功进行了解决&#xff0c;在这里进行一下记录…