標籤:load contract 編譯器 強制轉換 需要 ted 編譯 turn 不同類
Solidity中的基本類型轉換(十四)|入門系列
2017/4/29 posted in Solidity入門系列
點擊查看原文,獲得最佳化的排版。
- 隱式轉換
如果一個運算子能支援不同類型。編譯器會隱式的嘗試將一個運算元的類型,轉為另一個運算元的類型,賦值同理。
一般來說,實值型別間的互相轉換隻要不丟失資訊,語義可通則可轉換。下面,我們來看一個整數轉換的例子:
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。
- 顯式轉換
編譯器不會將文法上不可轉換的類型進行隱式轉換,此時我們要通過顯式轉換的方式,比如將一個有符號整數,轉為一個不帶正負號的整數。
pragma solidity ^0.4.0;
contract ExplicitConversion{
function f() returns (int8){
uint8 a = 1;
//強制轉換int8 b = int8(a);return b;
}
}
- 類型推斷
有時為了方便,我們不會顯式定義類型。但由於編譯器,會自動挑選一個最恰當的類型,所以會常常留下坑,我們來看這個例子:
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;
}
}
大家可以想想上述代碼啟動並執行結果。
上述代碼啟動並執行結果實際為2100。原因是因為var i = 0定義時,通過類型推斷,i的實際類型為uint8,所以它會一直迴圈,如果沒有count >= 2100這個判斷語句,這個迴圈將永遠不會結束。
- 一些常見的轉換方案
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))
}
}
}
Solidity中的基本類型轉換