{"content":{"title":"Solidity 构造函数","body":"回到我们的滚动 ERC20 示例，我们做了一些奇怪的事情，我们直接在合约中设置了 banker 变量。\r\n\r\n```solidity\r\ncontract ERC20 {\r\n    address public banker = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;\r\n\r\n    mapping(address => uint256) public balances;\r\n\r\n    function setSomeonesBalance(\r\n        address owner,\r\n        uint256 amount\r\n    )\r\n        public {\r\n            if (msg.sender == banker) {\r\n                balances[owner] = amount;\r\n            }\r\n            // 什么都不做\r\n    }\r\n\r\n    function transfer(\r\n        address receiver,\r\n        uint256 amount\r\n    )\r\n        public {\r\n            balances[msg.sender] -= amount;\r\n            balances[receiver] += amount;\r\n    }\r\n}\r\n```\r\n\r\n这没问题，但是如果有人想要部署合约并且将自己设置为 banker 呢？\r\n\r\n智能合约中有一个特殊的函数，在部署时被称为构造函数（constructor）。这与其他面向对象编程语言非常相似。下面是它的样子：\r\n\r\n```solidity\r\ncontract ExampleContract {\r\n    address public banker;\r\n\r\n    constructor() {\r\n        deployer = msg.sender;\r\n    }\r\n}\r\n```\r\n\r\n请注意，它是 “constructor()” 而不是 “function constructor()”，并且我们不指定 **public**，因为构造函数不能使用 pure、view、public 等修饰符进行修改。\r\n\r\n如果你希望 banker 由部署合约的人配置，那么你可以将其作为函数参数使用。\r\n\r\n```solidity\r\ncontract ExampleContract {\r\n    address public banker;\r\n\r\n    constructor(address _banker) {\r\n        banker = _banker;\r\n    }\r\n}\r\n```\r\n\r\n顺便提一句，你会在构造函数中看到这种模式：变量 = \\_变量。这在 Solidity 中不是必需的，但被视为一种惯例。\r\n\r\n在 Remix 上部署带有构造函数参数的合约时，你需要将参数放入出现在 “deploy” 旁边的框中。\r\n\r\n![https://static.wixstatic.com/media/61a666_a136b53ad685419582210f02b620e762~mv2.png/v1/crop/x_0,y_0,w_2000,h_973/fill/w_939,h_457,al_c,q_95,enc_auto/Constructor.png](https://img.learnblockchain.cn/2025/02/26/Constructor.png)\r\n\r\n**与其他函数不同，calldata 不能用于数组和字符串，必须使用 memory**\r\n\r\n再次强调，出于我们现在无法深入探讨的原因，构造函数参数中不能使用 calldata。我知道，这似乎是一个非常奇怪和随机的限制，但在你理解以太坊的底层原理后，这会变得有意义。\r\n\r\n以下是如何在构造时设置字符串：\r\n\r\n```solidity\r\ncontract ExampleContract {\r\n    string public name;\r\n\r\n    // 如果使用 calldata，编译时会出错\r\n    constructor(string memory _name) {\r\n        name = _name;\r\n    }\r\n}\r\n```\r\n\r\n你可能会想随意在任何地方使用 memory，而不去使用 calldata。但值得记住这一点，因为 calldata 会导致更便宜的交易（即用户更低的 gas 费用）。\r\n\r\n此外，如果你想知道，**构造函数不能返回值。**\r\n\r\n**练习题**\r\n\r\n[Deployer](https://github.com/RareSkills/Solidity-Exercises/tree/main/Deployer)\r\n\r\n### 了解更多与 RareSkills\r\n\r\n查看  [Solidity bootcamp](https://learnblockchain.cn/openspace/1) 以了解更多有关智能合约开发和代币标准的知识。\r\n\r\n \r\n\r\n>- 原文链接： [rareskills.io/learn-soli...](https://www.rareskills.io/learn-solidity/constructor)\r\n>- 登链社区 AI 助手，为大家转译优秀英文文章，如有翻译不通的地方，还请包涵～"},"author":{"user":"https://learnblockchain.cn/people/20722","address":null},"history":null,"timestamp":1740576463,"version":1}