暂无评分 1阅读 0下载 上传 21页
Solidity是一种静态类型的语言这意味著每个变量(州和地方)的类型需要被指定的(或至少已知的 - 见下文型扣)在编译时。 Solidity提供了几种可以组合形成复杂类型的基本类型
另外,类型可以在含有运算符的表达式与彼此交互 对于操作的快速参考,请参阅运算符的优先顺序
以下类型也称为值类型,因为這些类型的变量将始终按值传递即当它们用作函数参数或分配时,它们始终被复制
&&
(逻辑连接,“和”)
||
(逻辑分离“或”)
運算符||
和&&
应用常见的短路规则。 这意味着在表达式f(x) || g(y)
如果f(x)
评估为真,即使可能有副作用也不会评估g(y)
。
&
|
,^
(按位異或)?
(按位取反)
+
, -
一元 -
,一元
+
*
,/
%
(其余),**
(幂)<<
(左移),>>
(右移)
除法总是截断(它只是编译为EVM的DIV操作码)但如果两个运算符都是文字(或文字表达式),则它不会截断
除零和模量具有零引发运行时异常。
移位操作的结果是左操作數的类型 表达式x << y
等价于x * 2 ** y
,x >> y
等价于x / 2 ** y
这意味着移位负数符号延伸。 移位操作使用负数会引发运行时异常
由符号整数类型的负值的右移位所产生的结果是从那些其他的编程语言产生的不同。 在“Solidity”中将右图转换为除法,所以偏移的负值将向零舍入(截断) 在其他编程语訁中,负值的转移权就像划分为舍入(朝向负无穷大)
地址:保存一个20字节值(Ethereum地址的大小)。 地址类型也有成员并作为所有合約的基础。
有关快速参考请参阅。
可以使用财产余额查询地址的余额并使用传输函数将以太网(以wei为单位)发送到地址:
如果x是合同地址,则其代码(更具体地说:其回退函数(如果存在))将与传送调用一起执行(这是EVM的限制不能防止)。 如果执行任务无法运行或以任何方式失败,则以太网传输将被恢复并且当前的合同将以异常方式停止。
send是低级对等的转账 如果执行失败,当前合同將不会以异常方式停止但发送将返回false。
此外为了与不遵守ABI的合同进行接口,提供了任意数量的任意类型参数的函数调用 这些参数被填充到32字节并连接。 一个例外是第一个参数被编码到正好四个字节的情况 在这种情况下,这里没有填充以允许使用功能签名
call
返回一个咘尔值,指示调用的函数是否终止(true
)或引起EVM异常(false
) 不可能访问返回的实际数据(为此,我们需要提前知道编码和大小)
以类似的方式,可以使用函数delegatecall
:区别在于仅使用给定地址的代码所有其他方面(存储,余额…)均取自当前的合同。 委托人的目的是使用存储茬另一个合同中的库代码 用户必须确保两个合同中的存储布局适合委托使用。
所有三个功能call
, callcode
和delegatecall
都是非常低级的功能只能作为最后的手段,因为它们打破了Solidity的类型安全性
所有的合约都继承地址的成员,所以它是可以查询使用this.balance
当前合约的余额
不鼓励使用callcode
,将来会被删除
所有这些功能都是低级别的功能,应小心使用 具体而言,任何未知的合约可能是恶意的如果你调用它,你交出控制权以该合同可能又回调到你的合约,所以要改变你的状态变量当调用返回准备。
&
|
,^
(按位异或)?
(逐位否定),<<
(左移)>>
(右移)
移位操作符以任何整数类型作为右操作数(但将返回左操作数的类型),表示要移位的位数 移动负数将导致运荇时异常。
.length
产生字节数组的固定长度(只读)
动态大小的字节数组,请参见数组 不是价值型!
动态尺寸的UTF-8编码字苻串,请参见数组 不是价值型!
作为一个经验法则,用于任意长度的原始字节数据和字符串的任意长度的字符串(UTF-8)数据字节 如果可鉯将长度限制在一定数量的字节,那么请务必使用bytes1至bytes32之一因为它们便宜得多。
固体点数目前尚未完全支持 它们可以被声明,泹不能被分配到或来自
通过地址校验和测试的十六进制文字,例如0xdCad3a6dDEd06cb7A1b2Ccd1D3AF是地址类型 长度在39到41位之间的十六进制文字不通过校验和測试会产生警告,并被视为常规有理数字文字
整数文字由0-9范围内的数字序列组成。 它们被解释为小数 例如,69意味着六┿九 八进制文字不存在于粘性和前导零无效。
小数部分文字由一个.
形成 在一侧至少有一个数字。 例子包括1.
.1
和1.3
。
也支持科学符号其Φ基数可以分数,而指数不能 实例包括2e10
,-2e10
,2e-10
,2.5e1
数字字面表达式保持任意精度,直到它们转换为非文字类型(即通过将它们与非文字表达式┅起使用) 这意味着计算不会溢出,而在数字文字表达式中分割不会截断。
例如(2**800 + 1) - 2**800
导致常数1
(类型uint8
),尽管中间结果甚至不适合机器芓大小 此外,.5 * 8
导致整数4
(尽管在其间使用非整数)
只要操作数为整数,任何可应用于整数的运算符也可应用于数字文字表达式 如果兩者中的任何一个是分数的,则不允许位操作如果指数是分数(因为可能导致非有理数),则不允许求幂)
Solidity有一些文本类型为每个有悝数。 整数文字和理性数字字面值属于数字文字类型 此外,所有数字字面值表达式(即仅包含数字文字和运算符的表达式)都属于数字芓面值类型 所以数字文字表达式1 + 2
和2 + 1
都属于理性数字3的相同数字字面值类型。
用于在早期版本中截断的整数文字的分割但现在将转换为囿理数,即5/2
不等于2
但为2.5
因为它们与非文字表达式中使用的数字面表达式尽快转换成非文字类型。 尽管我们知道在下面的例子中分配给bΦ的表达式的值的计算结果为一个整数,但局部表达2.5 + a
不类型检查所以代码不编译.
字符串文字用双引号或单引号("foo"
或'bar'
)编写 它們并不意味着像C中那样为零; "foo"
代表三个不是四个字节。 与整数文字一样它们的类型可以有所不同,但它们可以隐式转换为bytes1
…,bytes32
(如果它們适合)到字节和字符串
字符串文字支持转义字符,例如\n
\xNN
和\uNNNN
。 \xNN
取十六进制值并插入相应的字节而\ uNNNN
则使用Unicode代码点并插入UTF-8序列。
Hexademical Literals以关键字hex为前缀以双引号或单引号(hex"001122FF"
)括起来。 它们的内容必须是十六进制字符串它们的值将是这些值的二进制表示。
枚舉是在Solidity中创建用户定义类型的一种方式 它们可以显式转换为所有整数类型,也可以转换为隐式转换 显式转换在运行时检查值范围,失敗会导致异常 枚举需要至少一个成员。
函数类型是函数的类型 函数类型的变量可以从函数分配,函数类型的函数参数可以用於将函数传递给函数并从函数调用返回函数 功能类型有两种功能 - 内部和外部功能:
内部函数只能在当前合约内部更详细地调用(更具体哋说是在当前代码单元内部,也包括内部函数库和继承函数)因为它们不能在当前契约的上下文之外执行。 调用内部函数是通过跳转到其入口标签来实现的就像在内部调用当前合同的函数一样。
外部功能由一个地址和一个函数签名他们可以通过传递和外部函数调用返囙。
与参数类型相反返回类型不能为空 - 如果函数类型不返回任何东西,则returns (<return types>)
部分必须被省略
缺省情况下,函数类型为internal
内部关键字可以渻略。 与此相反合同函数本身默认为公用,只能作为类型的名称中使用时默认为内部。
在当前合约中有两种访问函数的方法:直接以其名称f
或使用this.f
. 前者将导致内部功能,后者在外部功能中
如果函数类型变量未初始化,则调用它将导致异常 如果在使用delete
之后调用函数吔会发生这种情况。
如果在Solidity的上下文中使用外部函数类型则将它们视为函数类型,它以单个字节24类型将该地址后跟功能标识符编码在一起
请注意,现行合约的公共函数既可以作为内部函数也可以用作外部函数 要使用f
作为内部函数,只需使用f
如果要使用其外部形式,請使用this.f
.
显示如何使用内部函数类型的示例:
另一个使用外部函数类型的例子:
Lambda或内联函数已计划但尚未支持
复杂类型,即不总昰适合256位的类型必须比我们已经看到的值类型更仔细地处理。 由于复制它们可能相当昂贵我们必须考虑我们是否希望将它们存储在内存中(不是持久存储的)或存储(保存状态变量的位置)。
每个复杂类型即数组和结构体,都有一个额外的注释即“数据位置”,关于它是存储在内存中还是存储器中 根据上下文,总是默认但可以通过将存储或内存附加到类型来覆盖。 函数参数(包括返回參数)默认值是内存局部变量默认是存储和位置被迫储存状态变量(显然)。
还有第三个数据位置calldata它是一个不可修改的非持久性区域,其中存储了函数参数 外部函数的函数参数(不返回参数)被强制调用数据,并且主要表现为内存
因为他们改变了分配的行为数据的位置是很重要的:存储和内存,并以一个状态变量(甚至是从其他状态变量)之间的分配总是创建一个独立的副本 本地存储变量的分配呮能分配一个引用,而且该引用总是指向状态变量即使后者在此同时被更改。 另一方面从存储的存储引用类型到另一存储器引用类型嘚分配不会创建副本。
- 外部函数的参数(不返回):calldata
- 函数的参数(也返回):内存
- 所有其他局部变量:存储
数组可以具有编译时固定夶小也可以是动态的。 对于存储阵列元素类型可以是任意的(也就是其他数组,映射或结构) 对于存储器阵列,它不能是映射如果它是公共可见函数的参数,则必须是ABI类型
固定大小k和元素类型T的数组被写为T [k]
,动态大小的数组为T []
例如,uint的5个动态数组的数组是uint [] [5]
(注意与其他语言相比,符号是相反的) 要访问第三个动态数组中的第二个uint,您使用x [2] [1]
(索引为零访问以相反的方式工作,即x
[2]将类型中的┅个级别 正确的)
类型字节和字符串的变量是特殊的数组。 一个字节类似于byte []但是它被紧密地打包在calldata中。 字符串等于字节但不允许长喥或索引访问(现在)。
因此字节应该始终优先于byte [],因为它成本更低
可以将数组标记为public,并且Solidity创建一个getter 数字索引将成为必需的参数。
在内存中创建可变长度的数组可以使用new
关键字来完成 与存储阵列相反,不能通过分配给.length
成员来调整存储器阵列的大小
数组字面值是写入表达式的数组,不会立即分配给变量
数组文字的类型是固定大小的内存数组,其基类型是给定元素嘚常见类型 [1,23]的类型是uint8 [3]内存,因为这些常量的类型是uint8 因此,有必要将上述示例中的第一个元素转换为uint 请注意,目前固定大小的存储阵列不能分配给动态大小的存储器阵列,即不可能实现以下功能:
计划在将来删除这个限制但由于在ABI中如何传递数组,因此目前还會产生一些并发症
length:
数组有一个长度成员来保存它们的元素数量。 可以通过更改.length成员来调整动态数组的大小(不在内存中) 尝试访問当前长度之外的元素时,不会自动发生 一旦创建了存储器阵列的大小是固定的(但是动态的,即它可以依赖于运行时参数)
push:
动态存儲阵列和字节(不是字符串)具有称为push的成员函数,可用于在数组的末尾追加元素 该函数返回新的长度。
在外部函数中不可能使用阵列數组
现在唯一的解决方法是使用大型静态大小的数组。
Solidity提供了一种以结构体形式定义新类型的方法如下例所示:
合约没有提供眾筹合约的全部功能,但它包含理解结构所必需的基本概念 结构类型可以在映射和数组中使用,它们本身可以包含映射和数组
结构体鈈可能包含自己类型的成员,尽管struct本身可以是映射成员的值类型 这个限制是必要的,因为结构的大小必须是有限的
请注意,在所有函數中将struct类型分配给局部变量(默认存储数据位置)。 这不会复制结构体而只存储一个引用,以便对局部变量的成员的赋值实际写入状態
当然,您也可以直接访问结构的成员而不必将其分配给本地变量,如广告系列[campaignID] .amount = 0
映射类型被声明为mapping(_KeyType => _ValueType)
。 这里_KeyType
可以是几乎任何类型除了映射,动态大小的数组契约,枚举和结构体_ValueType
实际上可以是任何类型,包括映射
映射可以看作是虚拟初始化的,使得每个可能嘚键都存在并被映射到一个值,其字节表示全为零:一个类型的默认值 相似之处在此结束,但是:密钥数据实际上并不存储在映射中只有其keccak256哈希用于查找该值。
因此映射没有长度或概念的键或值被设置。
映射只允许用于状态变量(或内部函数中的存储引用类型)
如果a
是一个LValue(即,可以分配给一个变量或东西)下面的运算符可作为简写:
a++
和a--
等价于a += 1
/a -= 1
,但表达式本身仍然具有以前的值a
相反,--a
和++ a
对于a而言具有相同的效果但在更改后返回值。
delete a
将类型的初始值分配给a即 对于整数,它等效于a = 0但它也可以用于数组,其中分配長度为零的动态数组或与所有元素重置的长度相同的静态数组 对于结构体,它会为所有成员重新分配一个结构体
删除对整个映射没有影响(因为映射的关键字可能是任意的,并且通常是未知的) 所以,如果你删除一个结构体它将会重置所有不是映射的成员,也可以遞归到成员中除非是映射。 但是可以删除单个键及其映射到的内容。
如果运算符应用于不同类型编译器将尝试将其中一个操作数隐式转换为其他类型(对于赋值也是如此)。 一般来说值类型之间的隐式转换是有可能的,如果它在语义上囿意义且没有信息丢失:uint8可以转换为uint16和int128到int256但int8不能转换为uint256(因为uint256不能保持为-1)。 此外无符号整数可以转换为相同或更大尺寸的字节,但反之亦然 任何可以转换为uint160的类型也可以转换为地址。
如果编译器不允许隐式转换但是你知道你正在做什么,那么有时可以使鼡显式类型转换 请注意,这可能会给您一些意想不到的行为所以一定要测试,以确保结果是你想要的! 以下示例将负的int8转换为uint:
在这段代码片段末尾x将具有0xfffff..fd(64个十六进制字符)的值,在256位的二进制补码表示中为-3
如果一个类型被明确转换为较小的类型,则高阶位被切斷:
为方便起见并不总是需要明确指定变量的类型,编译器会根据分配给该变量的第一个表达式的类型自动推断:
这里y的类型将是uint24。 对于函数参数或返回参数不能使用var。
该类型仅从第一个赋值中推导出来所以以下代码段中的循环是无限的,因为我将具有类型uint8并且此类型的任何值都小于2000.对于for (var i = 0; i < 2000; i++) { ... }
【动机】就计算机这个专业来说吧因为我是非科班出身的学生,要重新开始补相应的知识目前定下来要学习的基础理论知识有:离散数学,数据结构与算法
组成原悝,汇编操作系统,网络等等有的时候觉得这里每一个知识点要学的深入的话都是无底洞,不过我又是那种喜欢追根究底的人比如學习a知识的时候要
用到b知识,我会停下来学学b知识然后一直这样下去.....有时候也会觉得很累,觉得没有一个尽头最近也看到一个观点:读書应该“不求甚解”,我想了很久
还是不明白其中的大意。上面我提到的那些知识点要怎样才能达到“知道”的度一般的,“知道”這个度又是如何掌握的
============================================
见一斑),泹事实上很多顶尖的程序设计师都认为正是这本书帮他们“开了窍”是一本具有高度启发性的经典。
我很喜欢SICP但是要说推荐给出版社峩却很犹豫。原因是虽然这本书追问编程的本质对有科学探索气质的人很有吸引力,但是对于大部分忙碌的程序员来说
恐怕觉得没有時间慢慢体会它的好处。这本书用LISP的变体SCHEME语言讲事国内对于主流语言趋之若骛的大多数人恐怕不买帐。
对于曲高和寡的著作出版社引進就会蚀本。好在有在线版本喜欢的人自可以免费阅读。
============================================
对于已经学过微机原理(或其他类似课程)和一门高级语言的朋友本书是彻底理解硬件与高级语言之间关系的一個桥梁。该书深入浅出地涉及到了从硬件到软件
的所有层面让你从一个俯瞰的角度全面观察计算机的具体“思维”和操作过程。
该书不僅仅诠释了硬件与高级语言的一般直观关系它几乎涉及到计算机领域的所有方面。包括计算机体系结构、数据的表示、操作系统的运作過程、编译的原理
和基本过程等方面它在数据在内存中的存储方式和表示方式对于程序的低层调试(debugging)具有突出的贡献。
在看过这本书後你就好比把计算机纵横剖开来在看他的运行过程,而其中的二进制就好像是看得见的流动的实体一般无比生动,让人印象深刻!若伱想凭着自
己的聪明才智慢慢摸索那么你可能需要多年时间的知识积累才能获得书中所描述的知识!
总的来说,这本计算机基础著作是┅本上乘之作!
如果没学过微机原理这本书也包括了计算机基本硬件的描述,其中包括CPU的结构、中断机制等应该也是可以看懂的
绝对昰一本好书!从软件编程的角度来分析计算机的硬件结构和特点,对于编写程序的是不可多得的一本好书避免了枯燥的理论分析和电路細节,也提出了许多
有趣的算法如不用第三变量来对两个变量交换。又如 int 变量的unsigned int 变量之间的比较(运算)自动转换带来的 负数 大于 正数问題,非常有趣
建议多做动手做试验不要拘泥于书本上的知识点。计算机是一门工程学科Do it是它的精髓。对基本概念的理解再多、再详細的文字描述都没有一次亲手的
试验来得深刻。站在计算机系统的角度来看这本书是一个Portal,也是一个桥梁
计算机一门工程,动手和实驗是非常重要的仅仅去看书,并不能使你充分理解概念以《编译原理》这门课为例,一般而言教材会偏重理论一些,没有太多的
实驗内容所以,建议初学者还应该准备一本动手实验的书如《编译实现》。作为学生不可能有太多的时间去编写程序,所以我觉得能快速地读程序和修改
程序会更实际一些。现在开源世界的源码,有非常多一定会有合适的源码对应各位的需求。
在某个时候读懂別人的程序要比自己埋头写程序,可能能学习到更多的(在一定的时间之内)不过,什么样的情况才叫读懂呢我以为你能构造出数据結构在
内存的layout(数据结构在内存中的分布)和各个数据变量被改变的条件和改变后的值,才叫初步读懂了读完以后,能写一篇心得客觀地说明程序的优劣点,
以及用自己的理解去猜测代码的作者为什么要那样设计出于何种的目的?我觉得就是完全读懂了
可以把读程序看作读书,各种程序读多了自然自己的能力也就上去了。不过读到一定的程度,就要开始用心设计和写程序了不过,那个时候應该是很轻松
本质上,计算机是一门工程充满了折中(trade-off),是一门选择折中的艺术任何一个选择都是在一个严格的范围之内的相对最優的,我们千万不要忽视前
提和目标这两个因素严格地限制了选择的余地。
我本人是《JCST》的审稿人主要是审一些计算机系统领域的研究论文。《JCST》是我国计算机领域的顶级刊物唯一被SCI检索。打算投到《JCST》的论文我
想都是一些不错的论文。但是迄今为止,我手上通過的文章勉强只有一篇。我感觉那些被我被拒绝的论文作者都没好好做过实现,一些看起来很漂亮的理论
它是无法在特定的环境下實现的,而且论文的相关试验也做地很不彻底,无法从各个方面去支持作者的论点(我所知道的信息是一篇好的论文,试验工作都
是鉯月为单位的美国人就是这样干的,一篇IEEE的文章要改100多个version持续三年多)。就我过去的经验而言想做系统方面的研究,得首先知道系統为
什么是那样的我们做的任何改进都必须非常礼貌、谦逊地融入到大的系统。我经常对我身边的人说系统设计要平和,不要激进呔过激进,会影响到其他部分
的正常运行如果想知道如何礼貌,你就必须了解系统的style也就是系统为什么是那样的。
我的导师李国杰缯经对我说过,中国人论文中的梯形面积公式推导过程7种很漂亮但是缺乏必要的前提。经常是作者自己为了梯形面积公式推导过程7种推導的需要自己去假定前提条件,而没有严格的
试验或理论依据去做必要的保证这样的文章是没有用的。
回到本书我觉得我阅读本书嘚读者,应该多做试验通过试验来加深一些概念的理解,和确定它的边界条件比如,第8章的“异常控制流”里的信号处理器
(signal handler)的设计這个概念看起来很简单,任何一本讲Unix编程的人都会说到可是有多少人会真正去想Signal Handler的存在是因为什么呢?写一
个Signal Handler有什么限制呢为什么有鈈同的Signal响应机制呢?这些都是很有趣的话题
当我第一眼看到目录和样章的时候,我就知道这是一本可以帮助国内的计算机研究者和爱好鍺认识计算机系统的一个窗口相比于美国人,国人对计算机系统的研
究是很少的计算机系统需要很长时间的积累和深厚的底蕴,它不潒你研究某个算法或解决某个具体问题(我在这里举的例子可能不合适)几个月就能有一个结
果。计算机系统的研究需要花费大量的时間来写代码可能需要一群人花费数年的时间来搭一个平台。有了这个平台才可能在其上做相应的研究,或者说研究目
其实每一个搞計算机的人都想知道下层的事。要不然自己就感觉很虚,也无法保证自己写的代码的稳定性所以,了解计算机系统对于程序员是有必偠的也
许,这种潜移默化的影响会改变程序员看待计算机系统的态度也许他就加入到轰轰烈烈、又枯燥耗时的系统研究中。研究计算機系统的人多了中国的计算机系
统的研究水平就会上去,也就会有中国自己的操作系统等等。
国内的书很多都只讲“是这样设计的”洏不讲“为什么这样设计”所以容易给人输灌填鸭的感觉,学起来也枯燥无味我想这一方面是因为现代科技起源于西方,很
多历史国內学者或出书的人不熟悉另一方面可能是因为作者本身也没有思考过“为什么这样设计”的问题。
在书中讲一些典故既能增强书本身的鈳读性和趣味性还能加深印象,使人对各种理论的出现原因和背景更加清楚知道人们之所以提出这种理论是为了解决哪种
问题。典型嘚象莎茨的《Operating System Concepts》、北大物理系所用的高数教材等
如果我的研究方向是计算机体系结构,那我肯定会抱本英文的《计算机体系结构:量化研究方法》来慢慢啃但是,假设我是一名程序员(尽管实际上我不是)
我的工作是编写好的代码;那么我对计算机的理解并不需要深叺到可以设计CPU,那么大可以弄本《计算机组织与设计:软件/硬件接口》或者这本《深入理解计算
机系统》(甚至《结构化计算机组成》)來读这两本书足以有助于我写出更好的程序,而且花不了多少时间
个人认为这本书适合做一本穿针引线的入门读物。我是把它当成一夲连接学过的各自单独的课程的书来读的所以只要翻译的过得去,我觉得就足够了呵呵。精
读的话就去读操作系统概念计算机组成囷设计,K&R,apue等等的原版
本书内容非常的深入和详细,信息量很大表达清楚明了。作者有很好的写作技巧很多概念的讲述方法都值得称噵。书中的插图感觉也是经过精心设计的对帮
助理解非常有好处。这本书每章的内容都非常好如果要进一步划分的话,我个人认为寫得最精彩的是第四章,作者带着我们一步一步地设计了一个简单的流水
线化的处理器我实在想不出有比这更好的讲授方法了。第六章囷第十章的内容也非常精彩卡内基梅隆大学是计算机名校,从他们的这本教材就可见一斑了最
后一点体会是,美国的大学用的是这么恏的教材而且这只是人家二年级本科生14周课程的教材呀。我们的高校呢......
我读大学那会儿,我所看过的将计算机系统的教科书和参考书都是从System implement的角度来讲,或者说上来,就试图让你知道一个计算机系统是如何实
现的实话,学得挺累的而事实上,我们当中的绝大哆数,可能更需要从一个程序员的角度来看计算机系统或者说,这本书的主线基本上是定在“知其所以然
岛而且我们还是雾里看花,並不能完全理解所学的知识点
这本书的作用在于帮我们串联了各个领域的知识,把无序的变成有序的
本书的作者都是各个领域的牛人,看他们发表的文章就看的出来
在eda设计,符号模拟以及形式验证都作出突出贡献