Solidity 是一种静态类型语言,这意味着每个变量(状态变量和局部变量)都需要在编译时指定变量的类型。
Solidity 提供了几种基本类型,并且基本类型可以用来组合出复杂类型。

除此之外,类型之间可以在包含运算符号的表达式中进行交互。
“undefined”或“null”值的概念在Solidity中不存在,但是新声明的变量总是有一个 默认值 ,具体的默认值跟类型相关。 要处理任何意外的值,应该使用错误处理来恢复整个交易,或者返回一个带有第二个bool 值的元组表示成功。
布尔值的取值范围为 true 和 false 。
默认值:false
pragma solidity ^0.8.0;
contract TestBool {
error NotEqual(bool A,bool B);
bool public A; // false
bool public B = true; //true
// require(A==B,"A not equal B");
if (A != B) {
error NotEqual(A,B);
}
}
运算符:
!(逻辑非)&& (逻辑与, “and” )|| (逻辑或, “or” )== (等于)!= (不等于)默认为int256
不同位长的整形范围如下:
int8 取值范围:-(2 ** 7)到 2 ** 7 -1int16取值范围:-(2 ** 15)到 2 ** 15 -1intX取值范围:-(2**X-1)到 2**(X-1) -1int256取值范围:-(2 ** 255)到 2 ** 255 -1默认为uint256
不同位长的整形范围如下:
uint8取值范围:0 到 2 ** 8 - 1uint16取值范围:0 到 2 ** 16 - 1uintX取值范围:0 到 2 ** X - 1uint256取值范围:0 到 2 ** 256 - 1运算符:
对于整形 X,可以使用 type(X).min 和 type(X).max 去获取这个类型的最小值与最大值。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract TestIntval {
int8 public i8 = -1;
int public i256 = 456;
int public i = -123; // int 等同于 int256
// int 的最大最小值
int public minInt = type(int).min;
int public maxInt = type(int).max;
uint8 public u8 = 1;
uint256 public u256 = 456;
uint public u = 123; // uint 等同于 uint256
// uint 的最大最小值
uint public minUInt = type(uint).min;
uint public maxUInt = type(uint).max;
function mini() public pure returns(uint8){
return type(uint8).max;
}
}
0.8.0 开始,算术运算有两个计算模式:一个是 “wrapping”(截断)模式或称 “unchecked”(不检查)模式,一个是”checked” (检查)模式。 默认情况下,算术运算在 “checked” 模式下,即都会进行溢出检查,如果结果落在取值范围之外,调用会通过 失败异常 回退。 你也可以通过 unchecked { ... }切换到 “unchecked”模式
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract C {
function f(uint a, uint b) pure public returns (uint) {
// 减法溢出会返回“截断”的结果
unchecked { return a - b; }
}
function g(uint a, uint b) pure public returns (uint) {
// 溢出会抛出异常
return a - b;
}
}

调用 f(2, 3)将返回 2**256-1, 而 g(2, 3) 会触发失败异常。
unchecked 代码块可以在代码块中的任何位置使用,但不可以替代整个函数代码块,同样不可以嵌套。
此设置仅影响语法上位于 unchecked 块内的语句。 在块中调用的函数不会此影响。
默认值: 0x0000000000000000000000000000000000000000
运算符:
示例:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract TestAddress {
//与其他机器语言相区别的类型就是这个address 类型,160-bit/20byte
address public myAddr = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
//合约自己的地址
address contractAddress = address(this);
//跟普通的地址类型一样,但多了两个方法 transfer/send 这两个方法后面章节会讲到
// address sender = payable(0x5B38Da6a701c568545dCfcB03FcB875f56beddC4);
//可以使用 balance 属性来查询一个地址的余额
function getBalance()
public view
returns (uint256, uint256)
{
require(myAddr.balance < contractAddress.balance, "1 must lg 2");
return (myAddr.balance, contractAddress.balance);
}
}

在计算机中的最小存储单位是 bit(位)
定长字节数组
bytes1 后面数字1是表示1字节 bytes默认等于bytes1
Bytes2 后面数字2是表示2字节
Bytes3 后面数字3是表示3字节
bytes4 后面数字4是表示4字节
...
bytes32 后面数字32是表示32字节
bytes32 等价于 int256或uint256 的位数
运算符
成员变量
.length 表示这个字节数组的长度(只读)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract BytesTest {
//定长字节数组,长度不可变
bytes1 public num1 = 0x12;
// bytes1 public num1 = 0x112; 溢出最大长度,这样会报错
// 也可以写成字符串类型
bytes4 public num2 = "0x12";
//也支持直接写 16 进制
bytes4 public num3 = 0x12121212;
//不足位的补0
bytes32 public num4 = 'abc'; //0x6162630000000000000000000000000000000000000000000000000000000000
function getlength1() public view returns (uint8) {
return num1.length;
}
function getlength2() public view returns (uint8) {
return num2.length;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract TestString {
string public myString = "hello";
string public myStringUnicl = unicode"你好"; //unicode 编码
string public myStringUnicl2 = unicode"你好😄"; //unicode 编码
// 两个字符串连接用 concat
function strConcat(string memory _a, string memory _b)
public
pure
returns (string memory)
{
return string.concat(_a, _b);
}
// 也可以转成bytes,bytes 和 string 可以互转
function bytesConcat(string memory _a, string memory _b) public pure returns (string memory){
bytes memory _ba = bytes(_a);
bytes memory _bb = bytes(_b);
bytes memory ret = bytes.concat(_ba,_bb);
return string(ret);
}
}
枚举可以在合约之外声明,也可在合约内声明.
默认取值为第一个元素的值
contract UserState {
// 枚举
//默认值是列表中的第一个元素
enum State {
Online, // 0
Offline, // 1
Unknown // 2
}
Status public status;
function get() public view returns (Status) {
return status;
}
// 通过将uint传递到输入来更新状态
function set(Status _status) public {
status = _status;
}
// 也可以是这样确定属性的更新
function off() public {
status = Status.Offline;
}
// delete 将枚举重置为其第一个值 0
function reset() public {
delete status;
}
}
您可以通过创建结构来定义自己的类型。
它们用于将相关数据分组在一起。
结构可以在合约之外声明,也可以在另一个合约中导入。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Structs {
struct Todo {
string text;
bool completed;
}
// 结构体数组
Todo[] public todos;
// 初始化结构的3种方法
function create(string calldata _text) public {
// 1.像函数一样调用它
todos.push(Todo(_text, false));
// 2. 键值对
todos.push(Todo({text: _text, completed: false}));
// 3.初始化一个空结构,然后更新它
Todo memory todo;
todo.text = _text;
todos.push(todo);// completed 没有定义,默认为 false
}
//通过索引获取结构体数组中一个元素,并更新内部的属性
function update(uint _index) public {
Todo storage todo = todos[_index];
todo.completed = !todo.completed;
}
}
映射是使用语法映射(keyType=>valueType)创建的。
keyType可以是任何内置值类型、字节、字符串或任何约定。
valueType可以是任何类型,包括另一个映射或数组。
映射不可迭代。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract Mapping {
//从地址到uint的映射
mapping(address => uint) public myMap;
function get(address _addr) public view returns (uint) {
//映射始终返回一个值。
//如果从未设置该值,它将返回默认值。
return myMap[_addr];
}
// 更新此地址的值
function set(address _addr, uint _i) public {
myMap[_addr] = _i;
}
function remove(address _addr) public {
//将值重置为默认值
delete myMap[_addr];
}
}
//嵌套 mapping
contract NestedMapping {
//嵌套映射(从地址映射到另一个映射)
mapping(address => mapping(uint => bool)) public nested;
function get(address _addr1, uint _i) public view returns (bool) {
// 可以从嵌套映射中获取值
return nested[_addr1][_i];
}
function set(
address _addr1,
uint _i,
bool _boo
) public {
nested[_addr1][_i] = _boo;
}
// 删除 mapping 的一个元素
function remove(address _addr1, uint _i) public {
delete nested[_addr1][_i];
}
}
初始化数组的几种方法
//初始化数组的几种方法
uint256[] public arr;
uint256[] public nums = [1, 2, 3];
//定长数组,所有元素初始化为 0
uint256[10] public myFixedSizeArr;
//未定义初始值的元素默认为 0
uint256[3] public three = [4, 5];
// 直接打印数组列表;
function getNums()
external
view
returns (
uint256[] memory,
uint256[] memory,
uint256[10] memory,
uint256[3] memory
)
{
return (arr, nums, myFixedSizeArr,three);
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Array {
//初始化数组的几种方法
uint256[] public arr;
uint256[] public nums = [1, 2, 3];
//定长数组,所有元素初始化为 0
uint256[10] public myFixedSizeArr;
uint256[3] public three = [4, 5, 6];
// 获取数组长度
function getLen() external view returns (uint256) {
return nums.length;
}
//向数组中添加值
function pushIndex(uint256 _x) external {
nums.push(_x);
}
// 这样删除数组不会改变数组长度,被删除的数字索引值会变成 0
function deleteIndex(uint256 _x) external {
delete nums[_x];
}
//不改变数组顺序情况下删除数组
//通过循环删除数组索引 [1,2,3,4] => [1,3,4,4] => [1,3,4]
function removeIndex(uint256 _x) public {
require(_x < nums.length, "out of index");
for (uint256 i = _x; i < nums.length - 1; i++) {
nums[i] = nums[i + 1];
}
nums.pop();
}
// 删除数组会改变元素的顺序,但是节省 gas
//[1,2,3,4]=> [1,4,3,4]=>[1,4,3]
function removeIndex2(uint256 _x) public {
require(_x < nums.length, "out of index");
nums[_x] = nums[nums.length - 1];
nums.pop();
}
//移除数组最后一个元素
function pop() external {
nums.pop();
}
//方法测试
function testRemove() external {
nums = [1, 2, 3, 4];
removeIndex(2);
assert(nums[0] == 1 && nums[1] == 2);
assert(nums[2] == 4);
assert(nums.length == 3);
}
}
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain
我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01 客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02 数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit
文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co