Solidity語法---動態(tài)大小字節(jié)數(shù)組(Dynamically-sized byte array)

Dynamically-sized byte array

  • string 是一個動態(tài)尺寸的UTF-8編碼字符串,它其實是一個特殊的可變字節(jié)數(shù)組,string是引用類型,而非值類型。

  • bytes 動態(tài)字節(jié)數(shù)組,引用類型。

根據(jù)經驗,在我們不確定字節(jié)數(shù)據(jù)大小的情況下,我們可以使用string或者bytes,而如果我們清楚的知道或者能夠將字節(jié)書控制在bytes1 ~ bytes32,那么我們就使用bytes1 ~ bytes32,這樣的話能夠降低存儲成本。

常規(guī)字符串 sting 轉換為 bytes

string字符串中沒有提供length方法獲取字符串長度,也沒有提供方法修改某個索引的字節(jié)碼,不過我們可以將string轉換為bytes,再調用length方法獲取字節(jié)長度,當然可以修改某個索引的字節(jié)碼。

pragma solidity ^0.4.4;

contract C {
    
    bytes9 public g = 0x6c697975656368756e;
    
    string public name = "liyuechun";
    
    function gByteLength() constant returns (uint) {
        
        return g.length;
    }
    
    function nameBytes() constant returns (bytes) {
        
        return bytes(name);
    }
    
    function nameLength() constant returns (uint) {
        
        return bytes(name).length;
    }
    
    function setNameFirstByteForL(bytes1 z) {
        
        // 0x4c => "L"
        bytes(name)[0] = z;
    }
}
function nameBytes() constant returns (bytes) {
        
    return bytes(name);
}

nameBytes這個函數(shù)的功能是將字符串name轉換為bytes,并且返回的結果為0x6c697975656368756e。0x6c697975656368756e一共為9字節(jié),也就是一個英文字母對應一個字節(jié)。

function nameLength() constant returns (uint) {
        
    return bytes(name).length;
}

我們之前講過,string字符串它并不提供length方法幫助我們返回字符串的長度,所以在nameLength方法中,我們將name轉換為bytes,然后再調用length方法來返回字節(jié)數(shù),因為一個字節(jié)對應一個英文字母,所以返回的字節(jié)數(shù)量剛好等于字符串的長度。

function setNameFirstByteForL(bytes1 z) {
    
    // 0x4c => "L"
    bytes(name)[0] = z;
}

如果我們想將name字符串中的某個字母進行修改,那么我們直接通過x[k] = z的形式進行修改即可。xbytes類型的字節(jié)數(shù)組,k是索引,zbyte1類型的變量值。

setNameFirstByteForL方法中,我就將liyuechun中的首字母修改成L,我傳入的z的值為0x4c,即大寫的L。

漢字字符串或特殊字符的字符串轉換為bytes

特殊字符

pragma solidity ^0.4.4;

contract C {
    
    
    string public name = "a!+&520";
    

    function nameBytes() constant returns (bytes) {
        
        return bytes(name);
    }
    
    function nameLength() constant returns (uint) {
        
        return bytes(name).length;
    }
}

在這個案例中,我們聲明了一個name字符串,值為a!+&520,根據(jù)nameBytesnameLength返回的結果中,我們不難看出,不管是字母、數(shù)字還是特殊符號,每個字母對應一個byte(字節(jié))。

中文字符串

pragma solidity ^0.4.4;

contract C {
    
    
    string public name = "黎躍春";
    

    function nameBytes() constant returns (bytes) {
        
        return bytes(name);
    }
    
    function nameLength() constant returns (uint) {
        
        return bytes(name).length;
    }
}

在上面的代碼中,我們不難看出,黎躍春轉換為bytes以后的內容為0xe9bb8ee8b783e698a5,一共9個字節(jié)。也就是一個漢字需要通過3個字節(jié)來進行存儲。那么問題來了,以后我們取字符串時,字符串中最好不要帶漢字,否則計算字符串長度時還得特殊處理。

創(chuàng)建bytes字節(jié)數(shù)組

pragma solidity ^0.4.4;

contract C {
    
    
    bytes public name = new bytes(1);
    
    
    function setNameLength(uint length) {
        
        name.length = length;
    }
    
    function nameLength() constant returns (uint) {
        
        return name.length;
    }    
}

bytes可變數(shù)組length和push兩個函數(shù)的使用案例

pragma solidity ^0.4.4;

contract C {
    
    // 0x6c697975656368756e
    // 初始化一個兩個字節(jié)空間的字節(jié)數(shù)組
    bytes public name = new bytes(2);
    
    // 設置字節(jié)數(shù)組的長度
    function setNameLength(uint len) {
        
        name.length = len;
    }
    
    // 返回字節(jié)數(shù)組的長度
    function nameLength() constant returns (uint) {
        
        return name.length;
    }
    
    // 往字節(jié)數(shù)組中添加字節(jié)
    function pushAByte(byte b) {
        
        name.push(b);
    }
    
}

說明:當字節(jié)數(shù)組的長度只有2時,如果你通過push往里面添加了一個字節(jié),那么它的長度將變?yōu)?,當字節(jié)數(shù)組里面有3個字節(jié),但是你通過length方法將其長度修改為2時,字節(jié)數(shù)組中最后一個字節(jié)將被從字節(jié)數(shù)組中移除。

總結

對比分析:

  • 不可變字節(jié)數(shù)組

我們之前的文章中提到過如果我們清楚我們存儲的字節(jié)大小,那么我們可以通過bytes1,bytes2,bytes3,bytes4,……,bytes32來聲明字節(jié)數(shù)組變量,不過通過bytesI來聲明的字節(jié)數(shù)組為不可變字節(jié)數(shù)組,字節(jié)不可修改,字節(jié)數(shù)組長度不可修改。

  • 可變字節(jié)數(shù)組

我們可以通過bytes name = new bytes(length) - length為字節(jié)數(shù)組長度,來聲明可變大小和可修改字節(jié)內容的可變字節(jié)數(shù)組。

原文:Solidity Types - 動態(tài)大小字節(jié)數(shù)組(Dynamically-sized byte array)
作者:黎躍春

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容