solidity学习过程---参数传递类型

变量使用

解决问题:

  1. 数据类型:
  • 什么是值类型
  • 什么是引用类型
  1. 使用方式:
  • 值传递
  • 引用传递

数据类型:

  • 值类型:变量的存储空间存的是变量的数据 —(全部皆为值传递)
  • 引用类型:变量的存储空间存的是变量数据所在的存储空间的地址

数据传递:

  • 值传递和引用传递。值类型的变量,赋值是简单的值传递,即两个变量占有独立的存储区域。引用类型赋值传递的是变量的引用,即两个变量指向同一存储区域
  • 实例:A向B索求某个URL,如果B给A这个URL,那么A与B都将共享这个网页,如果A与B某一方修改了这个网页,那么这种变化两者都是可见的; –引用传递
    但是如果B是将这个网页打印出来,然后给A,那么B无论之后对这个网页做出什么改变,那么A将不会看到。–值传递

细节使用

  • 如果一个变量是值类型,给它赋值时永远是值传递,函数参数传递时永远是值传递;
  • 如果一个变量是引用类型,给它赋值时可以是值,也可以是引用,这决定于该变量是Storage类型还是Memory类型。

solidity中变量类型

  1. 值类型
  • 布尔(Booleans)
  • 整型(Integer)
  • 地址(Address)
  • 定长字节数组(fixed byte arrays)
  • 有理数和整型(Rational and Integer Literals,String literals)
  • 枚举类型(Enums)

2.引用类型

  • 不定长字节数组(bytes)
  • 字符串(string)
    -数组(Array)
    -结构体(Struts)

solidity 代码实例

当函数参数为memory类型时,相当于值传递,而storage类型的函数参数将是指针传递。

  1. 值传递与引用传递 代码来自于
contract SandwichFactory {
  struct Sandwich {
    string name;
    string status;
  }
  Sandwich[] sandwiches;
  function eatSandwich(uint _index) public {
    // Sandwich mySandwich = sandwiches[_index];
    /*
       看上去很直接,不过 Solidity 将会给出警告,告诉你应该明确在这里定义 `storage` 或者 `memory`。
       所以你应该明确定义 `storage`:
    */
    Sandwich storage mySandwich = sandwiches[_index];
    // 这样 `mySandwich` 是指向 `sandwiches[_index]`的指针在存储里,另外...
    mySandwich.status = "Eaten!";
    // 这将永久把 `sandwiches[_index]` 变为区块链上的存储,如果你只想要一个副本,可以使用`memory`:
    Sandwich memory anotherSandwich = sandwiches[_index + 1];
    // 这样 `anotherSandwich` 就仅仅是一个内存里的副本了
    // 另外
    anotherSandwich.status = "Eaten!";
    // 将仅仅修改临时变量,对 `sandwiches[_index + 1]` 没有任何影响
    // 不过你可以这样做:
    sandwiches[_index + 1] = anotherSandwich;
    // 如果你想把副本的改动保存回区块链存储
  }
}
  1. 关于memory与solidity不同类型赋值情况
  • 存储变量到存储变量 – 创建数据副本(数据副本仅仅是对赋值数据的拷贝)
  • 存储变量到内存变量 – 创建数据副本
  • 内存变量到存储变量 – 创建数据副本
  • 内存变量到内存变量 – 对于引用类型的局部变量,从一个内存变量到另一个数据变量不会产生副本(引用传递),
    对于值类型的局部变量,仍然会创建一个数据副本(值传递)

contract LocationsFromStoS {
 // M -- memory  S --- storage
 //修改第二变量的值,仅仅是为了整明第一变量获取到的仅仅是第二个变量的数据拷贝
  uint public stateVar1 = 10;
  uint stateVar2 = 20;

  function doSomething() public returns (uint, uint) {

   stateVar1 = stateVar2;
   stateVar2 = 30;

   return (stateVar1, stateVar2); //returns 20,30
  }
}


contract LocationsFromMtoS {

    uint public stateVar = 10; //storage

    function doSomething(uint _x) public returns(uint, uint) {

        stateVar = _x;
        _x = 21;

        return (stateVar, _x); //returns 20,40
    }
}


contract LocationsFromStoM {

    uint stateVar = 10; //storage
    string public name = "renln";

    function doSomething() public returns(uint, uint) {

        uint localVar = 20; //memory

        localVar = stateVar;
        stateVar = 40;

        return (localVar, stateVar); //returns 10,40
    }
    function doSomething1(string memory _localname) public returns(string memory) {
    //   bytes memory btsName = bytes(name);
      bytes memory btsLocalname = bytes(_localname);

     name = string(btsLocalname);
     btsLocalname = "Renln";

        return (string(btsLocalname));
    }
}


contract LocationsFromMtoM {
    //引用类型
    function doSomething()
        public pure returns(uint[] memory, uint[] memory) {

        uint[] memory localMemoryArray1 = new uint[](3);
        localMemoryArray1[0] = 4;
        localMemoryArray1[1] = 5;
        localMemoryArray1[2] = 6;

        uint[] memory localMemoryArray2 = localMemoryArray1;
        localMemoryArray1[0] = 10;

        return (localMemoryArray1, localMemoryArray2);
       //returns 10,5,6 | 10,5,6
    }
    //值类型 修改_localVar2只是为了整明—_localVar1是获取到_localVar1的数据拷贝
    function doSomething1(uint _localVar1, uint _localVar2) public pure returns(uint, uint) {

       _localVar1 = _localVar2;  // _localVar1:11,_localVar2:22
       _localVar2 = 40;

       return (_localVar1, _localVar2); //returns 20
   }
}

发布了7 篇原创文章 · 获赞 1 · 访问量 240

猜你喜欢

转载自blog.csdn.net/qq_35434814/article/details/104742975