当前位置: 首页 > wzjs >正文

住房和城乡建设部网站建造师网站链接分析工具

住房和城乡建设部网站建造师,网站链接分析工具,wordpress升级主题,wordpress网址打不开文章目录 映射类型可迭代映射 映射类型 映射类型使用语法 mapping(KeyType KeyName? > ValueType ValueName?),映射类型的变量声明使用语法 mapping(KeyType KeyName? > ValueType ValueName?) VariableName。 KeyType 可以是任何内置值类型、bytes、st…

文章目录

  • 映射类型
      • 可迭代映射

在这里插入图片描述

映射类型

映射类型使用语法 mapping(KeyType KeyName? => ValueType ValueName?),映射类型的变量声明使用语法 mapping(KeyType KeyName? => ValueType ValueName?) VariableName

KeyType 可以是任何内置值类型、bytesstring 或任何合约类型或枚举类型。其他用户定义的复杂类型,如映射、结构体或数组类型是不允许的。

ValueType 可以是任何类型,包括映射、数组和结构体。

KeyNameValueName 是可选的(因此 mapping(KeyType => ValueType) 也是有效的),它们可以是任何有效的标识符,但不能是类型。

你可以将映射看作哈希表,它在内部初始化,每个可能的键都会映射到一个值,该值的字节表示是全零,即类型的默认值。相似之处仅限于此,键数据不会存储在映射中,只有它的 keccak256 哈希值用于查找值。

由于这个原因,映射没有长度或键值是否已设置的概念,因此无法在没有额外信息的情况下删除映射。

映射只能有存储数据位置,因此只能作为状态变量、作为函数中的存储引用类型,或者作为库函数的参数。它们不能作为合约函数的公共参数或返回参数。这些限制也适用于包含映射的数组和结构体。

你可以将映射类型的状态变量标记为公共的,Solidity 会为你自动创建一个 getter。KeyType 变为 getter 的一个参数,并使用 KeyName(如果指定的话)。如果 ValueType 是值类型或结构体,getter 返回与该类型匹配的 ValueType(如果指定了 ValueName)。如果 ValueType 是数组或映射,则 getter 会有一个参数对应每个 KeyType,并递归处理。

在下面的示例中,MappingExample 合约定义了一个公共的 balances 映射,键类型为 address,值类型为 uint,将以太坊地址映射到无符号整数值。由于 uint 是值类型,getter 返回一个与该类型匹配的值,在 MappingUser 合约中,你可以看到它返回指定地址的值。

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;// 定义一个包含地址和余额的映射的合约
contract MappingExample {// 声明一个公共的映射,address => uint,记录每个地址的余额mapping(address => uint) public balances;// 更新函数:允许发送者更新他们的余额function update(uint newBalance) public {balances[msg.sender] = newBalance;  // 将调用者的余额更新为 newBalance}
}// 定义一个合约用于与 MappingExample 合约进行交互
contract MappingUser {// 一个函数,用来调用 MappingExample 合约的 update 方法,并返回当前合约地址的余额function f() public returns (uint) {// 创建 MappingExample 合约的实例MappingExample m = new MappingExample();// 调用 update 函数,将余额设置为 100m.update(100);// 返回当前合约地址的余额return m.balances(address(this));  // 返回 MappingExample 合约中当前合约地址的余额}
}

下面的示例是一个简化版的 ERC20 代币。_allowances 是一个映射类型,嵌套在另一个映射类型内部。我们为映射提供了可选的 KeyNameValueName。这不会影响合约的功能或字节码,它仅仅是在 ABI 中为映射的 getter 输入和输出设置了名称字段。

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.18;// 定义一个包含映射的智能合约
contract MappingExampleWithNames {// 定义一个 public 映射,映射地址(address)到余额(uint)。映射的键为 `user`,值为 `balance`。// 这个映射会自动生成一个 getter 函数,可以根据地址(address)查询对应的余额。mapping(address user => uint balance) public balances;// 更新余额的函数,接受一个 `newBalance` 参数。// 这个函数会将调用者(msg.sender)的余额更新为 `newBalance`。function update(uint newBalance) public {// 使用调用者的地址(msg.sender)作为键,更新其对应的余额值。balances[msg.sender] = newBalance;}
}

在下面的示例中,_allowances 映射用于记录某人被授权从你的账户中提取的金额:

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.22 <0.9.0;contract MappingExample {// 定义一个私有映射 `_balances`,将每个地址映射到一个无符号整数(余额)。mapping(address => uint256) private _balances;// 定义一个私有映射 `_allowances`,它是一个二层映射,记录每个地址(owner)允许另一个地址(spender)提取的金额。mapping(address => mapping(address => uint256)) private _allowances;// 定义事件,当转账发生时触发。event Transfer(address indexed from, address indexed to, uint256 value);// 定义事件,当批准时触发,表明某个地址被授权从另一个地址提取一定金额。event Approval(address indexed owner, address indexed spender, uint256 value);// 查询某个地址被授权的提取金额function allowance(address owner, address spender) public view returns (uint256) {return _allowances[owner][spender];}// 从一个账户向另一个账户转账,同时检查授权金额是否足够function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {// 确保 sender 允许 msg.sender(调用者)提取足够的金额require(_allowances[sender][msg.sender] >= amount, "ERC20: Allowance not high enough.");// 减少授权金额_allowances[sender][msg.sender] -= amount;// 执行转账_transfer(sender, recipient, amount);return true;}// 批准另一个地址(spender)从调用者的账户中提取指定金额(amount)function approve(address spender, uint256 amount) public returns (bool) {// 确保 spender 地址不是零地址require(spender != address(0), "ERC20: approve to the zero address");// 设置授权金额_allowances[msg.sender][spender] = amount;// 触发批准事件emit Approval(msg.sender, spender, amount);return true;}// 内部转账函数,用于更新账户余额,并触发转账事件function _transfer(address sender, address recipient, uint256 amount) internal {// 确保 sender 和 recipient 不是零地址require(sender != address(0), "ERC20: transfer from the zero address");require(recipient != address(0), "ERC20: transfer to the zero address");// 确保 sender 有足够的余额require(_balances[sender] >= amount, "ERC20: Not enough funds.");// 执行转账:从 sender 减去金额,给 recipient 增加金额_balances[sender] -= amount;_balances[recipient] += amount;// 触发转账事件emit Transfer(sender, recipient, amount);}
}

可迭代映射

你不能直接迭代映射,即不能枚举它们的键。不过,你可以在其基础上实现一个数据结构并对其进行迭代。例如,下面的代码实现了一个 IterableMapping 库,User 合约将数据添加到该库中,并且 sum 函数会迭代这个数据结构以求和所有值。

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.8;// 定义 IndexValue 结构体,用于存储每个键对应的索引和数值
struct IndexValue { uint keyIndex; // 键的索引位置uint value;    // 键对应的值
}// 定义 KeyFlag 结构体,用于标记键是否被删除
struct KeyFlag { uint key;      // 键的值bool deleted;  // 是否已删除标志
}// 定义 itmap 结构体,包含了一个映射和一个存储键的数组,以及当前大小
struct itmap {mapping(uint => IndexValue) data; // 存储键值对的映射KeyFlag[] keys;                   // 存储键的数组uint size;                         // 数据大小
}// 定义一个类型 Iterator,实质上是 uint 类型,用于遍历
type Iterator is uint;// 定义 IterableMapping 库,提供操作 itmap 类型数据的函数
library IterableMapping {// 插入数据到 itmap 中,如果已存在则更新数据function insert(itmap storage self, uint key, uint value) internal returns (bool replaced) {uint keyIndex = self.data[key].keyIndex; // 获取当前键的索引self.data[key].value = value;            // 更新该键对应的值if (keyIndex > 0) {return true; // 如果键已经存在,返回 true,表示数据已替换} else {// 如果键不存在,分配一个新的索引keyIndex = self.keys.length;self.keys.push(); // 在数组末尾添加一个新元素self.data[key].keyIndex = keyIndex + 1; // 设置新键的索引self.keys[keyIndex].key = key; // 将键添加到键数组中self.size++; // 增加数据大小return false; // 返回 false,表示插入了新的键值对}}// 从 itmap 中删除指定的键function remove(itmap storage self, uint key) internal returns (bool success) {uint keyIndex = self.data[key].keyIndex; // 获取该键的索引if (keyIndex == 0) {return false; // 如果键不存在,返回 false}delete self.data[key]; // 删除数据映射中的键值对self.keys[keyIndex - 1].deleted = true; // 将对应的 KeyFlag 标记为已删除self.size--; // 减小数据大小return true; // 返回 true,表示删除成功}// 检查 itmap 中是否包含指定的键function contains(itmap storage self, uint key) internal view returns (bool) {return self.data[key].keyIndex > 0; // 如果该键存在,返回 true}// 初始化遍历,返回一个迭代器function iterateStart(itmap storage self) internal view returns (Iterator) {return iteratorSkipDeleted(self, 0); // 跳过已删除的项,返回起始迭代器}// 检查当前迭代器是否有效function iterateValid(itmap storage self, Iterator iterator) internal view returns (bool) {return Iterator.unwrap(iterator) < self.keys.length; // 如果迭代器位置小于键数组长度,则有效}// 获取下一个迭代器,跳过已删除的项function iterateNext(itmap storage self, Iterator iterator) internal view returns (Iterator) {return iteratorSkipDeleted(self, Iterator.unwrap(iterator) + 1); // 跳到下一个有效项}// 获取当前迭代器对应的键和值function iterateGet(itmap storage self, Iterator iterator) internal view returns (uint key, uint value) {uint keyIndex = Iterator.unwrap(iterator); // 获取迭代器的索引key = self.keys[keyIndex].key;             // 获取键value = self.data[key].value;              // 获取值}// 跳过已删除的项,返回有效的迭代器位置function iteratorSkipDeleted(itmap storage self, uint keyIndex) private view returns (Iterator) {while (keyIndex < self.keys.length && self.keys[keyIndex].deleted) // 如果该项被标记为删除,则跳过keyIndex++;return Iterator.wrap(keyIndex); // 返回跳过已删除项后的迭代器}
}// User 合约使用 IterableMapping 库进行数据操作
contract User {itmap data; // 声明一个 itmap 类型的变量来保存数据// 使用 IterableMapping 库来操作 itmap 类型的数据using IterableMapping for itmap;// 插入数据到 itmap 中function insert(uint k, uint v) public returns (uint size) {// 调用 IterableMapping 库的 insert 函数插入数据data.insert(k, v);// 返回当前数据的大小return data.size;}// 计算所有存储数据的总和function sum() public view returns (uint s) {// 遍历 itmap 中的所有数据并计算总和for (Iterator i = data.iterateStart(); // 初始化迭代器data.iterateValid(i); // 检查迭代器是否有效i = data.iterateNext(i) // 获取下一个有效项) {(, uint value) = data.iterateGet(i); // 获取当前项的值s += value; // 将当前值累加到总和}}
}

文章转载自:

http://euObMYcj.wgbmj.cn
http://ZUHm4fh5.wgbmj.cn
http://lQQzeSCU.wgbmj.cn
http://LJQR6Za9.wgbmj.cn
http://8siCtDrG.wgbmj.cn
http://JTLcB6yL.wgbmj.cn
http://TcZj72DH.wgbmj.cn
http://pq784e0B.wgbmj.cn
http://umUsvDoR.wgbmj.cn
http://dkgS7Dhz.wgbmj.cn
http://CoYscEQl.wgbmj.cn
http://gJ80AyXr.wgbmj.cn
http://XGyQPHkZ.wgbmj.cn
http://QaEgm04N.wgbmj.cn
http://EDdWKz9Y.wgbmj.cn
http://IeH78EBh.wgbmj.cn
http://rQMRO9cb.wgbmj.cn
http://VPzduPB9.wgbmj.cn
http://IFYS4FJI.wgbmj.cn
http://6zNOx6qb.wgbmj.cn
http://w95OaVQP.wgbmj.cn
http://sxmAOpKL.wgbmj.cn
http://DifIC96l.wgbmj.cn
http://ULjBQluG.wgbmj.cn
http://WSBJOtAs.wgbmj.cn
http://MiXoRR2c.wgbmj.cn
http://h2uMkkQk.wgbmj.cn
http://DCRsLw7F.wgbmj.cn
http://qatpSdMm.wgbmj.cn
http://zfPHKlzv.wgbmj.cn
http://www.dtcms.com/wzjs/609350.html

相关文章:

  • 手机网站用什么域名wordpress模板如何安装
  • 郑州网站推广优化外包公司网站的服务与建设岗位职责
  • 免费建网站软件下载惠州房产网
  • 响应式网站好处连云港百度推广总代理
  • 一般做网站费用合肥seo排名优化公司
  • 微信互动营销网站建设济南建设工程招标网
  • 在线咨询 1 网站宣传wordpress打开网站前广告
  • 自己做的网站给人攻击了怎么办广东省建设工程交易中心
  • 建设电子商务网站前的市场分析苏州营销型网站制作
  • 网站优化常见的优化技术简单的logo设计图片
  • 网站建设哪家公司比较好网站主机免备案吗
  • 网站推广都做什么内容以下哪个选项不属于网络营销的特点
  • wordpress 主题站创建网站是怎么赚钱的
  • 网站历史快照最新闻头条新闻
  • 网站建设 开发工具 python建行手机银行下载app最新版
  • 安阳网站建设哪家好维港豪宅项目网站建设
  • 简约大气网站模板甘肃省省经合局网站建设的通知
  • 做游戏网站的目地济宁网站建设公司公司
  • 平凉网站开发昆山外发加工网
  • 公司备案查询网站茶叶建设网站的优势
  • 网站建设的广告语兰州网站建设小程序
  • 百度网站推广服务商企业信用信息查询公示系统网址
  • 建设会计协会网站青海兴远建设工程有限公司网站
  • 上海高端网站建设公司哪家好Wordpress出现错误
  • 国外设计工作室网站南宁网站制作超薄网络
  • 遂溪网站建设公司情侣做记录网站源码
  • 网站5g空间网站推广经典案例
  • 灵武网站建设企业网站轮播图
  • WordPress外贸企业站主题淘宝上的网站建设可信
  • 婚恋网站排名前10厦门市保障性住房官网