Solidity学习::(13)类型转换

类型转换


类型转换,是一个十分重要,常用的手段

一、隐式转换

隐式转换,就是当一个运算符能支持不同类型,编译器会隐式的尝试将一个操作数的类型,转为另一个操作数的类型,赋值同理。

条件是:值类型间的互相转换只要不丢失信息,语义可通则可转换。

             就是说,uint8可转换到uint16、uint32、、、等,但不能反过来

             同样的,无符号整数可以被转为同样,或更大的字节的类型。但需要注意的是,不能反过来转换。由于address是                20字节大小,所以它与int160大小是一样。【因此可用隐式转换将int160转换到address】

如:

//转换例子1
pragma solidity ^0.4.0;

contract Int{
  function conversion() returns (uint16){
    uint8 a = 1;
    //隐式转换
    uint16 b = a;
    return (b);
  }
}

//转换例子2
pragma solidity ^0.4.0;

contract IntToAddress{
  function f() returns (uint){
    uint160 i = 10;
    address addr = i; //int160隐式转换到address
    return addr.balance;
  }
}

二、显式转换

不能隐式转换是,需要显式转换,如有符号整数转换到无符号整数(8位有符号的负数,转换到无符号8位,则-1 ===> 255,    -2===>254  以此类推)

即需要添加强制类型转换符号,来实现转换

 如:

pragma solidity ^0.4.0;

contract ExplicitConversion{
  function f() returns (uint8){
    int8 a = -2;

    //强制转换
    uint8 b = uint8(a);
    return b;
  }
}

三、 使用Var的坑

先看下面代码,并推算返回结果:

pragma solidity ^0.4.4;

contract Test{
    function a() returns (uint){
      uint count = 0;
        for (var i = 0; i < 2000; i++) {
            count++;
            if(count >= 2100){
                break;
            }
        }
        return count;
    }
}

正常看,循环到1999就结束了,count应该为2000

实际上,返回的count值为2100

原因是,Var变量,为编译器自动选择合适的变量,这里选择了uint8,那么i最大255,超过之后又从0开始,因此,仅凭for括号中的条件判断,并不能跳出循环,直到count大于等于2100,才能跳出循环。

四、 常用转换方案

(1)uint转换到bytes

function toBytes(uint256 x) returns (bytes b) {
    b = new bytes(32);
    assembly { mstore(add(b, 32), x) }
}

(2)string转换到bytes

string可以显示的转为bytes。但如果要转为bytes32,可能只能使用assembly

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))
    }
  }
}

全文参考:http://me.tryblockchain.org/solidity-conversions.html#fn1

猜你喜欢

转载自blog.csdn.net/dieju8330/article/details/82992689