类型 您所在的位置:网站首页 位操作符可以用于实型、空类型或其他复杂类型 类型

类型

2024-07-07 07:14| 来源: 网络整理| 查看: 265

函数类型

函数类型是一种表示函数的类型。可以将一个函数赋值给另一个函数类型的变量, 也可以将一个函数作为参数进行传递,还能在函数调用中返回函数类型变量。 函数类型有两类:- 内部(internal) 函数和 外部(external) 函数:

内部函数只能在当前合约内被调用(更具体来说, 在当前代码块内,包括内部库函数和继承的函数中), 因为它们不能在当前合约上下文的外部被执行。 调用一个内部函数是通过跳转到它的入口标签来实现的, 就像在当前合约的内部调用一个函数。

外部函数由一个地址和一个函数签名组成,可以通过外部函数调用传递或者返回。

函数类型表示成如下的形式:

open in Remix

function () {internal|external} [pure|view|payable] [returns ()]

与参数类型相反,返回类型不能为空 —— 如果函数类型不需要返回, 则需要删除整个 returns () 部分。

默认情况下,函数类型是内部函数,所以可以省略 internal 关键字。 注意,这只适用于函数类型。对于合约中定义的函数, 必须明确指定其可见性,它们没有默认类型。

转换:

当且仅当它们的参数类型相同,它们的返回类型相同,它们的内部/外部属性相同, 并且 A 的状态可变性比 B 的状态可变性更具限制性时, 一个函数类型 A 就可以隐式转换为一个函数类型 B。特别是:

pure 函数可以转换为 view 和 非 payable 函数

view 函数可以转换为 非 payable 函数

payable 函数可以转换为 非 payable 函数

其他函数类型之间的转换是不可能的。

关于 payable 和 非 payable 的规则可能有点混乱, 但实质上,如果一个函数是 payable,这意味着 它也接受零以太的支付,所以它也是 非 payable。 另一方面,一个 非 payable 的函数将拒收发送给它的以太, 所以 非 payable 的函数不能被转换为 payable 的函数。 声明一下,拒收以太比不拒收以太更有限制性。 这意味着您可以用一个不可支付的函数覆写一个可支付的函数,但不能反过来。

此外,当您定义一个 非 payable 的函数指针时, 编译器并不强制要求被指向的函数实际拒收以太。 相反,它强制要求该函数指针永远不会被用来发送以太。 这使得我们有可能将一个 payable 的函数指针分配给一个 非 payable 的函数指针, 以确保这两种类型的函数表现相同,即都不能用来发送以太。

如果一个函数类型的变量没有被初始化,调用它将导致 会出现 异常。如果您在一个函数上使用了 delete 之后再调用它, 也会发生同样的情况。

如果外部函数类型在 Solidity 的上下文中被使用, 它们将被视为 function 类型,它将地址和函数标识符一起编码为一个 bytes24 类型。

请注意,当前合约的公共函数既可以被当作内部函数也可以被当作外部函数使用。 如果想将一个函数当作内部函数使用,就用 f 调用, 如果想将其当作外部函数,使用 this.f 。

一个内部类型的函数可以被分配给一个内部函数类型的变量,无论它在哪里被定义。 这包括合约和库的私有,内部和公共函数,以及自由函数。 另一方面,外部函数类型只与公共和外部合约函数兼容。

备注

带有 calldata 参数的外部函数与带有 calldata 参数的外部函数类型不兼容。 它们与相应的带有 memory 参数的类型兼容。 例如,没有一个函数可以被 function (string calldata) external 类型的值所指向, 而 function (string memory) external 可以同时指向 function f(string memory) external {} 和 function g(string calldata) external {}。 这是因为对于这两个位置,参数是以同样的方式传递给函数的。 调用者不能直接将其calldata传递给外部函数,总是ABI将参数编码到内存中。 将参数标记为 calldata 只影响到外部函数的实现,在调用者一方的函数指针中是没有意义的。

库合约被排除在外,因为它们需要 delegatecall, 并且 对它们的选择器使用不同的 ABI 约定。 接口中声明的函数没有定义,所以指向它们也没有意义。

成员: 外部(或公共)函数有以下成员:

.address 返回该函数的合约地址。

.selector 返回 ABI 函数选择器

备注

外部(或公共)函数曾经有额外的成员 .gas(uint) 和 .value(uint)。 这些在 Solidity 0.6.2 中被废弃,并在 Solidity 0.7.0 中被移除。取而代之的是 使用 {gas: ...} 和 {value: ...} 来分别指定发送到函数的气体量或以太(wei为单位)量。 参见 外部函数调用 以获得更多信息。

以下例子展示如何使用这些成员:

open in Remix

// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.6.4 =0.4.16


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有