Solidity中的基本类型转换
Solidity中的基本类型转换(⼗四)|⼊门系列
2017/4/29 posted in Solidity⼊门系列
点击查看原⽂,获得优化的排版。
1. 隐式转换
如果⼀个运算符能⽀持不同类型。编译器会隐式的尝试将⼀个操作数的类型,转为另⼀个操作数的类型,赋值同理。
⼀般来说,值类型间的互相转换只要不丢失信息,语义可通则可转换。下⾯,我们来看⼀个整数转换的例⼦:
pragma solidity ^0.4.0;
contract Int{
function conversion() returns (uint16){
uint8 a = 1;
//隐式转换
uint16 b = a;
return (b);
}
}
上⾯的例⼦中,我们将⼀个uint8的变量a隐式的转换为了uint16。同理它还⽀持转为uint32,uint128和uint256。
另外,⽆符号整数可以被转为同样,或更⼤的字节的类型。但需要注意的是,不能反过来转换。由于address是20字节⼤⼩,所以它与int160⼤⼩是⼀样。
pragma solidity ^0.4.0;
contract IntToAddress{
function f() returns (uint){
uint160 i = 10;
address addr = i;
return addr.balance;
}
}
上⾯的例⼦中,将uint160的i转为了⼀个address。
2. 显式转换
编译器不会将语法上不可转换的类型进⾏隐式转换,此时我们要通过显式转换的⽅式,⽐如将⼀个有符号整数,转为⼀个⽆符号整数。
pragma solidity ^0.4.0;
contract ExplicitConversion{
function f() returns (int8){
uint8 a = 1;
//强制转换
int8 b = int8(a);
return b;
}
}
3. 类型推断
有时为了⽅便,我们不会显式定义类型。但由于编译器,会⾃动挑选⼀个最恰当的类型,所以会常常留下坑,我们来看这个例⼦:
pragma solidity ^0.4.4;
contract Test{
function a() returns (uint){
uint count = 0;
for (var i = 0; i < 2000; i++) {
soliditycount++;
if(count >= 2100){
break;
}
}
return count;
}
}
⼤家可以想想上述代码运⾏的结果。
上述代码运⾏的结果实际为2100。原因是因为var i = 0定义时,通过类型推断,i的实际类型为uint8,所以它会⼀直循环,如果没有count >= 2100这个判断语句,这个循环将永远不会结束。
4. ⼀些常见的转换⽅案
uint转为bytes
将⼀个uint转转bytes,可以使⽤assembly1。
function toBytes(uint256 x) returns (bytes b) {
b = new bytes(32);
assembly { mstore(add(b, 32), x) }
}
上⾯的转换⽅式可能是效率最⾼的⽅式。
string转为bytes
string可以显⽰的转为bytes。但如果要转为bytes32,可能只能使⽤assembly2。
pragma solidity ^0.4.0;
contract StringToBytes{
function StringToBytesVer1(string memory source) returns (bytes result) {
return bytes(source);
}
function stringToBytesVer2(string memory source) returns (bytes32 result) {
assembly {
result := mload(add(source, 32))
}
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论