函数参数,包括返回值的默认数据存储位置是memory。
局部变量的默认数据存储位置是storage。
状态变量默认数据存储位置强制为storage
使用new创建的memory的数组,不能使用length改变长度
改小数组长度,被移除的元素会被销毁
function f() returns (uint, bool, uint) {
return (7, true, 2);
}
(data.length,) = f(); // Sets the length to 7 设定长度为7
(,data[3]) = f(); // Sets data[3] to 2 将data[3] 设为2
在函数中任何位置声明的变量,它的作用域为整个函数,与声明位置无关
(1)在以下情况下会生成assert风格异常:
以过大或负数索引访问数组(比如x[i] ,i >= x.length 或 i < 0)
以过大或负数索引访问固定长度的bytesN。
除数或模数为零(例如5/0或23%0)。
对负数进行位移
将过大或负数转化为枚举类型。
调用内部函数类型的0初始化(zero-initialized)变量。
assert的条件为false
(2)在以下情况下会生成require风格异常:
调用throw
调用require并且条件为false
通过消息调用来调用函数,但是它没有正确完成(即,用尽了gas,没有匹配的函数,或者抛出了异常),除非使用底层别的操作call,send,delegatecall或callcode。 底层别的操作不会抛出异常,而是通过返回false来表示失败。
使用new关键字创建合约但是失败。
执行一个外部函数调用,其指向不包含代码的合约。
合约通过public函数接收Ether,但没有payable修饰符。包括构造函数和回退函数。
合约通过一个public的getter函数接收Ether。
如果.transfer()失败。
(3)assert风格的异常消耗调用中可用的所有gas,而require风格的异常将不会消耗从Metropolis版本开始的任何gas。
编译器会自动为所有public状态变量创建getter函数。
getter函数具有外部可见性。
如果在内部访问符号(即不使用this.关键字),则将其作为状态变量。
如果它是外部访问的(即使用this.),则将其作为函数。
网友评论