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

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

Unlike other programming languages, Swift doesn’t require you to create separate interface and implementation files for custom structures and classes. In Swift, you define a structure or class in a single file, and the external interface to that class or structure is automatically made available for other code to use.

An instance of a class is traditionally known as anobject. However, Swift structures and classes are much closer in functionality than in other languages, and much of this chapter describes functionality that applies to instances ofeithera class or a structure type. Because of this, the more general terminstanceis used.

Comparing Structures and Classes

Structures and classes in Swift have many things in common. Both can:

  • Define properties to store values
  • Define methods to provide functionality
  • Define subscripts to provide access to their values using subscript syntax
  • Define initializers to set up their initial state
  • Be extended to expand their functionality beyond a default implementation
  • Conform to protocols to provide standard functionality of a certain kind

简单翻译过来就是:

与其他编程语言不同,Swift不需要为自定义结构体和类创建单独的接口和实现文件。在Swift中,您在单个文件中定义一个结构体或类,该类或结构体的外部接口将自动提供给其他代码使用。

类的实例传统上称为对象。然而,Swift结构体和类在功能上比在其他语言中更接近

比较结构和类

Swift中的结构体和类有很多共同点。都可以:

  • 定义属性来存储值
  • 定义方法来提供功能
  • 定义下标以使用下标语法提供对其值的访问
  • 定义初始化器来设置它们的初始状态
  • 扩展以扩展其功能,使其超出默认实现
  • 遵守协议以提供某种标准功能

结构体和类最大的区别就是结构体是值类型,类是引用类型。

这里提醒一下Swift值类型列表:

  • 结构体
  • 枚举
  • 元组(tuple)
  • 基本类型(Int,Double,Bool等)
  • 集合(Array, String, Dictionary, Set)

引用类型最常用的就是类和闭包。

在 Swift 中,值类型,存放在栈区;引用类型,存放在堆区。但是有些值类型,如字符串或数组,会间接地将项保存在堆中。所以它们是由引用类型支持的值类型。

Swift 中,值类型的赋值为深拷贝(Deep Copy),值语义(Value Semantics)即新对象和源对象是独立的,当改变新对象的属性,源对象不会受到影响,反之同理。

引用类型的赋值是浅拷贝(Shallow Copy),引用语义(Reference Semantics)即新对象和源对象的变量名不同,但其引用(指向的内存空间)是一样的,因此当使用新对象操作其内部数据时,源对象的内部数据也会受到影响。

struct Boy {var name = "Lilei"var age = 12
}
var boyA = Boy()
print("boyA.name -> (boyA.name)")var boyB = boyA
boyB.name = "Tom"
print("boyA.name -> (boyA.name)")控制台输出结果为:boyA.name -> LileiboyA.name -> Lilei

Boy为结构体的时候更改boyB的name boyA.name 并没有改变

class Boy: NSObject {var name = "Lilei"var age = 12
}
var boyA = Boy()
print("boyA.name -> (boyA.name)")var boyB = boyA
boyB.name = "Tom"
print("boyA.name -> (boyA.name)")
print(Unmanaged.passUnretained(boyA).toOpaque())
print(Unmanaged.passUnretained(boyB).toOpaque())控制台输出结果为:boyA.name -> LileiboyA.name -> Tom0x0000600002e2b9e00x0000600002e2b9e0

Boy为class的时候更改boyB的name boyA也会改变,同时boyA的地址和boyB的地址相同可见在class中拷贝为指针拷贝,从中即可发现,两个变量指向的是同一块内存空间。

在swift4.0中 可以用==来判断两个对象是否是同一个对象

if boyA == boyB {print("boyA == boyB")}
控制台输出结果为:boyA == boyB

嵌套类型

在使用过程中会存在嵌套的情况

值类型嵌套值类型:

struct Boy {var name = "Lilei"var age = 12var dog = Dog()}struct Dog {var weight = 40var name = "littleDog"}
var boyA = Boy()
var boyB = boyAboyB.name = "Tom"
boyB.dog.name = "bigDog"
boyB.dog.weight = 100print(boyA,boyA.dog)
print(boyB,boyB.dog)控制台输出:Boy(name: "Lilei", age: 12, dog: swift_test.Dog(weight: 40, name: "littleDog")) Dog(weight: 40, name: "littleDog")Boy(name: "Tom", age: 12, dog: swift_test.Dog(weight: 100, name: "bigDog")) Dog(weight: 100, name: "bigDog")

结构体嵌套结构体,很显然赋值时创建了新的变量,两者是独立的,嵌套的值类型变量也会创建新的变量,这两者也是独立的。boyA和boyB 不同,dogA和dogB也不同

值类型嵌套引用类型:

把Dog改成Class

struct Boy {var name = "Lilei"var age = 12var dog = Dog()
}class Dog:NSObject {var weight = 40var name = "littleDog"
}
var boyA = Boy()
var boyB = boyA
boyB.name = "Tom"
boyB.dog.name = "bigDog"
boyB.dog.weight = 100print(boyA,boyA.dog,boyA.dog.name)
print(boyB,boyB.dog,boyB.dog.name)
控制台输出结果:Boy(name: "Lilei", age: 12, dog: <swift_test.Dog: 0x600001d110e0>) <swift_test.Dog: 0x600001d110e0> bigDogBoy(name: "Tom", age: 12, dog: <swift_test.Dog: 0x600001d110e0>) <swift_test.Dog: 0x600001d110e0> bigDog

可以看出boyB发生了变化,boyB的dog和boyA的dog为同一个对象,值类型嵌套引用类型时,赋值时创建了新的变量,两者是独立的,但嵌套的引用类型指向的是同一块内存空间,当改变值类型内部嵌套的引用类型变量值时(除了重新初始化),其他对象的该属性也会随之改变。

引用类型嵌套值类型:

Boy改成class,Dog为struct

class Boy: NSObject {var name = "Lilei"var age = 12var dog = Dog()
}struct Dog {var weight = 40var name = "littleDog"
}
var boyA = Boy()
var boyB = boyA
boyB.name = "Tom"
boyB.dog.name = "bigDog"
boyB.dog.weight = 100print(boyA,boyA.dog,boyA.dog.name)
print(boyB,boyB.dog,boyB.dog.name)
控制台输出:<swift_test.Boy: 0x600003853480> Dog(weight: 100, name: "bigDog") bigDog<swift_test.Boy: 0x600003853480> Dog(weight: 100, name: "bigDog") bigDog

引用类型嵌套值类型时,赋值时创建了新的变量,但是新变量和源变量指向同一块内存,因此改变源变量的内部值,会影响到其他变量的值。

引用类型嵌套引用类型:

class Boy: NSObject {var name = "Lilei"var age = 12var dog = Dog()
}struct Dog {var weight = 40var name = "littleDog"
}
var boyA = Boy()
var boyB = boyA
boyB.name = "Tom"
boyB.dog.name = "bigDog"
boyB.dog.weight = 100print(boyA,boyA.dog,boyA.dog.name)
print(boyB,boyB.dog,boyB.dog.name)
控制台输出:<swift_test.Boy: 0x6000029c4120> <swift_test.Dog: 0x6000027d0fa0> bigDog<swift_test.Boy: 0x6000029c4120> <swift_test.Dog: 0x6000027d0fa0> bigDog

引用类型嵌套引用类型时,赋值时创建了新的变量,但是新变量和源变量指向同一块内存,内部引用类型变量也指向同一块内存地址,改变引用类型嵌套的引用类型的值,也会影响到其他变量的值。

总结:

类和结构体的选择:

  • 该数据结构的主要目的是用来封装少量相关简单数据值;
  • 有理由预计该数据结构的实例在被赋值或传递时,封装的数据将会被拷贝而不是被引用;
  • 该数据结构中储存的值类型属性,也应该被拷贝,而不是被引用;
  • 该数据结构不需要去继承另一个既有类型的属性或者行为。

当有上面的一种情况或多种情况请选择结构体,结构体比类更简单,也就是更轻便。

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

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

相关文章

DS5020配置集群存储

一、方案设计 计划给某公司服务器制作集群&#xff0c;存储划分大致如下&#xff1a; 1、 将存储磁盘制作为raid5&#xff1b; 2、 划分两个Storage Partition给两类集群使用&#xff0c;一类为数据库服务&#xff0c;一类为各种应用服务 二、存储的连接 1、存储的简介 Serial …

RequireJS首次加载偶尔失败

现象&#xff1a;第一次加载JS文件&#xff0c;首次加载偶尔失败&#xff1b; 原因&#xff1a;require([jquery, operamasks, zTree, jQueryCookie]&#xff0c;中前后引用同步加载&#xff1b; 解决方式&#xff1a;shim声明前置加载&#xff1b; 配置如下&#xff1a; requi…

linux之file命令总结

解释&#xff1a; file是通过查看文件的头部内容&#xff0c;来获取文件的类型使用file命令可以知道某个文件究竟是二进制&#xff08;ELF格式&#xff09;的可执行文件, 还是Shell Script文件&#xff0c;或者是其它的什么格式。 file能识别的文件类型&#xff1a;目录、Shel…

优化.NET 应用程序 CPU 和内存的11 个实践

https://michaelscodingspot.com/cpu-bound-memory-bound/优化.NET 应用程序 CPU 和内存的11 个实践凡事都有其限度&#xff0c;对吧&#xff1f;汽车只能开这么快&#xff0c;进程只能使用这么多内存&#xff0c;程序员只能喝这么多咖啡。我们的生产力受到资源的限制&#xff…

陈省身:三角形内角和不等于180°

全世界只有3.14 % 的人关注了爆炸吧知识三角形外角和为360作为公认的劳模&#xff0c;平日里&#xff0c;超模君不但要码字&#xff0c;工作之余还要监督表妹做作业&#xff0c;也难怪表妹成绩总是能名列前茅。今天表妹做作业时&#xff0c;遇到一道判断题&#xff1a;“三角形…

跟我学PHP第二篇- 配置Mysql以及PHP WampServer篇(1)

大家好&#xff0c;昨天我给大家介绍了如何去安装ZEND STUDIO&#xff0c;下面昨天文章的链接&#xff1a; http://www.cnblogs.com/kmsfan/p/zendStudio.html 本节为配置的第一部分&#xff0c;还没有讲完全部&#xff0c;因为个人工作比较忙&#xff0c;没有一整天时间写博客…

linux之查看文件大小和磁盘大小总结

1 、查看文件大小 使用du命令,查看该目录以及子目录文件的大小 du -h 如果只需要快速查看这个目录占用大小&#xff0c;可用下面命令 du -sh 比如我们查看xiaoyun这个文件大小 2、查看电脑磁盘大小 使用下面命令 df -h 效果如下图 很明显系统装载/dev/sda2下

YARP(Yet Another Reverse Proxy)是使用 .NET 构建的高度可定制的反向代理

点击上方蓝字关注我们&#xff08;本文阅读时间&#xff1a;16分钟)YARP 1.0已经发布了&#xff0c;现在可以从 NuGet 下载。YARP&#xff08;Yet Another Reverse Proxy&#xff09;是使用 .NET 构建的高度可定制的反向代理。YARP 与其他反向代理的最大区别在于它是如何构建和…

电影院里为何有散落的青瓜?

1 摄像头&#xff1a;你套个袋子我就认不出来了吗&#xff1f;▼2 路边惊现大熊猫&#xff01;&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼3 好一个驼小姐&#xff08;via.豆瓣社死小组满杯草莓&#xff09;▼4 学弟的理解也不是无迹可寻▼5 台湾人过生日的方…

java中List、Map、Set、Collection、Stack、Queue等的使用

java中这几个东西是比较常用的&#xff0c;虽然我用的不多&#xff0c;也正是因为用的不多&#xff0c;所以我一直搞不清楚他们之间的具体用法以及相互之间的关系&#xff0c;现在特单独作为一个东西来总结一下。 本文参考一下资料&#xff1a; 1.《java编程思想》一书第11章 2…

开发文档模板_需求文档模板一堆什么样的适合你呢?

产品经理的日常中用的最多的是产品需求文档&#xff0c;这个文档应该可以说是产品经理将需求落到是明面上的一步。我们的文档需要给相关的人员进行共同的看&#xff0c;不然文档就没有存在的意义了&#xff0c;文档不只是简单的线框图和一些自己也看不明白的词汇。实际中很少开…

Briefly unavailable for scheduled maintenance message after doing automatic upgrade

为什么80%的码农都做不了架构师&#xff1f;>>> 今天突然不能打开wordpress&#xff0c;报了“Briefly unavailable for scheduled maintenance message after doing automatic upgrade” 这个错误&#xff0c;一下懵逼了。 Google之后&#xff0c;发现是wordpress…

搞IT的技术人员为什么会如此苦逼

http://www.cnblogs.com/springmvc-hibernate/archive/2012/05/10/2493733.html —————————————————————————————————————————————————————— 为什么苦逼&#xff1f; 原因一大堆&#xff0c;对于外部的因数&#xff0c;我…

为什么越来越多的开发者选择使用Spring Boot

Web应用开发背景 使用Java做Web应用开发已经有近20年的历史了&#xff0c;从最初的Servlet1.0一步步演化到现在如此多的框架&#xff0c;库以及整个生态系统。经过这么长时间的发展&#xff0c;Java作为一个成熟的语言&#xff0c;也演化出了非常成熟的生态系统&#xff0c;这…

【Blog.Core开源】快速预览Admin界面效果

( 半盏屠苏犹未举&#xff0c;灯前小草写桃符 )书接上文《【Blog.Core开源】开发插件&#xff0c;给Swagger加权》&#xff0c;在上篇文章中&#xff0c;我们给项目的接口文档增加了一个控制界面&#xff0c;可以输入用户名密码&#xff0c;这样也算是简单的一个加密控制了&…

视图添加字段_Odoo开发教程2-为模型添加字段

开启开发者模式后&#xff0c;我们可通过菜单 Settings > Technical > Database Structure > Models来查看模型的定义。这时搜索 res.partner(未安装其它应用的情况下第一个即是)&#xff0c;对应的模型描述为 Contact。点击打开表单视图&#xff0c;这时就可以看到 p…

改变listview中item选中时文字的颜色

摘要 当listview的某个item选中时&#xff0c;默认有个选中的高亮显示&#xff0c;如果你要自定义选中时的高亮显示效果&#xff0c;可以在listview中设置属性 android:listSelector"drawable/item_selector" 其中 item_selector 是在drawable目录下定义的一个xml文件…

安卓学习笔记2

1.IntentFilter Intent详解 http://www.cnblogs.com/engine1984/p/4146621.html <activity android:name".SecondActivity"><intent-filter><action android:name"hello1" /><action android:name"hello2" /><cate…