本文简述了结构体和类的基本定义,并且说明他们二者的区别,结构体是值类型,类是引用类型。区别于其他语言,Swift提供的标准库中大部分公开类型都是结构体,而非类。
主要内容:
- 结构体
- 类
- 结构体和类的区别
在Swift标准库中,绝大多数的公开类型都是结构体,而枚举和类只占很小一部分
比如Bool、Int、Double、String、Array、Dictionary其实都是结构体类型。

初始化器实现:
/*
1、结构体的初始化器
注意:初始化器必须保证所有存储属性都完成初始化
*/
struct Point1 {
var x: Int = 5
var y: Int
}
//此时都有值
var p11 = Point1(x: 10, y: 10)
//xYou自己的初始值5
var p12 = Point1(y: 10)
//y没值
//var p3 = Point(x:5)
//x、y都没值
//var p4 = Point()
说明:
本质:初始化器中给存储属性赋初始值
代码:
struct WYPoint {
var x: Int = 0
var y: Int = 0
}
var p = WYPoint()
查看汇编


说明:
初始化器实现:
/*
2、自定义初始化器
*/
struct Point2 {
var x : Int = 0
var y : Int = 0
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
//只有这个初始化器
var p21 = Point2(x: 10, y: 10)
//系统不再提供默认初始化器
//var p22 = Point2(y: 10)
//var p23 = Point2(x:5)
//var p24 = Point2()
说明:
代码:
/*
3、结构体的内存查看
*/
struct Point3 {
var x: Int = 0
var y: Int = 0
var origin: Bool = false
}
print(MemoryLayout<Point3>.size) // 17
print(MemoryLayout<Point3>.stride) // 24
print(MemoryLayout<Point3>.alignment) // 8
说明:
类的定义和结构体是类似的,但是编译器并没有为类自动生成可以传入成员值的初始化器,只有一个空构造。
类默认只有一个空的构造器,但是这个空构造中也必须给成员变量赋值
虽然可以定义存储属性、计算属性、方法、下标,但是真正类的内存中存储的只有存储属性(可以理解为OC的成员变量)
类的初始化器也必须要给所有的存储属性赋值
代码:
/*
1、类的初始化器
*/
//没有给存储属性赋值,类的定义会报错
//class Point4 {
// var x: Int
// var y: Int
//}
//let p41 = Point4()//报错,没有给存储属性赋初始值
//只有空构造
class Point5 {
var x: Int = 0
var y: Int = 0
}
let p51 = Point5()//空构造中赋初始值,不报错
//let p52 = Point5(x: 10,y: 20)//默认没有其他构造器
//let p53 = Point5(x: 10)//默认没有其他构造器
//let p54 = Point2(y: 20)//默认没有其他构造器
说明:
注意:
反初始化器可以理解为析构器(C++)
代码;
/*
2、类的反初始化器
*/
class Person {
var x: Int = 0
var y: Int = 0
deinit {
print("WY:Perosn对象销毁了")
}
}
func testInit() -> Void {
var person = Person()
}
testInit()//WY:Perosn对象销毁了
//继承关系中的反初始化器
class Student : Person {
deinit {
print("WY:Student对象销毁了")
}
}
func testInit2() -> Void {
var student = Student()
}
//WY:Student对象销毁了
//WY:Perosn对象销毁了
testInit2()
说明:
这里和OC是一样的,占用内存大小为8字节对齐,分配内存大小为16字节对齐
详情可以查看我的另一篇博客苹果的内存对齐原理
代码:
//类的内存大小分析
func testInstanceSize() {
class Point {
var x = 11//8
var test = true//1
var y = 22//8
}//33、40、48
let p = Point()
print(class_getInstanceSize(type(of: p)))//40 print(class_getInstanceSize(Point.self))
print(Mems.size(ofRef: p))//48
}
testInstanceSize()
说明:
本质区别在于结构体是值类型,类是引用类型。
区别:
Swift的引用类型和值类型的区别在C++、OC、Java的概念都是一样的,有一定编码基础的同学肯定都接触过,便不在此赘述了
注意:
在Swift标准库中,为了提升性能,String、Array、Dictionary、Set当不出现写入修改时,是浅拷贝,如果是会出现写入的情况则是深拷贝
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择
有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url
在Ruby类中,我重写了三个方法,并且在每个方法中,我基本上做同样的事情:classExampleClassdefconfirmation_required?is_allowed&&superenddefpostpone_email_change?is_allowed&&superenddefreconfirmation_required?is_allowed&&superendend有更简洁的语法吗?如何缩短代码? 最佳答案 如何使用别名?classExampleClassdefconfirmation_required?is_a
下面例子中的Nested和Child有什么区别?是否只是同一事物的不同语法?classParentclassNested...endendclassChild 最佳答案 不,它们是不同的。嵌套:Computer之外的“Processor”类只能作为Computer::Processor访问。嵌套为内部类(namespace)提供上下文。对于ruby解释器Computer和Computer::Processor只是两个独立的类。classComputerclassProcessor#Tocreateanobjectforthisc
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
可能已经问过了,但我找不到它。这里有2个常见的情况(对我来说,在编程Rails时......)用ruby编写是令人沮丧的:"astring".match(/abc(.+)abc/)[1]在这种情况下,我得到一个错误,因为字符串不匹配,因此在nil上调用[]运算符。我想找到的是比以下内容更好的替代方法:temp="astring".match(/abc(.+)abc/);temp.nil??nil:temp[1]简而言之,如果不匹配,则简单地返回nil而不会出错第二种情况是这样的:var=something.very.long.and.tedious.to.writevar=some
我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。
给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最