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

基于以太坊的智能合约开发Solidity(函数继承篇)

参考教程:【实战篇】1、函数重载_哔哩哔哩_bilibili

1、函数重载:

pragma solidity ^0.5.17;contract overLoadTest
{//不带参数function test() public{}//带一个参数function test(address account) public{}//参数类型不同,虽然uint160可以和address直接转化,但仍然满足重载的条件 function test(uint160 account) public{}//参数个数不同function test(uint160 account,address otherAccount) public{}// 此函数会编译报错,因为重载不考虑函数的返回值类型是否相同// function test(address account) returns(address sender){//     return msg.sender;// }uint public result = 0; function negativeExample1(uint id) public{result = 100; }function negativeExample1(uint8 id) public{result = 200;}function test1() public{//negativeExample1(1);  该语句会报错,因为传入函数的参数1既符合uint又符合uint8,        solidity无法辨别调用哪一个函数}function negativeExample2(address account) public{result = 100;}function negativeExample2(uint160 account) public {result = 200;}function test2() public{//negativeExample2(1);  该语句会报错,address本质上就是一个uint160的一串数字,solidity无法辨别调用哪一个函数}
}

当一些行为模式一致,但是这个行为所输入的参数不一样时,便构成了重载,具体表现如下:

①函数的名字相同

②函数的参数不同(类型、数量)

③与函数的返回值无关

2、函数命名参数:

pragma solidity ^0.5.17;contract functionParamTest
{uint public id;string public name;function setParam(uint _id,string memory _name) public {id = _id;name = _name;}function test() public{setParam(18,"xiaofang");  //正常地传参}function test2() public{setParam({_id:18,_name:"xiaofang"});  //通过形参名给函数传参}function test3() public{setParam({_name:"xiaofang",_id:18});  //顺序可以与定义函数参数时不同(在较多参数情况下命名参数对于代码的可读性有很好的提升)}  function test4() public{setParam(18);  //调用函数传参时不可缺少参数,否则编译会报错(在外部调用函数时可以缺少参数,但不建议缺少)}
}

3、函数返回值的特性:

pragma solidity ^0.5.17;contract functionReturnTest
{//最常规的返回值写法  function test() public view returns(uint){return 10;}//返回值也可以进行一个命名,在returns后可以声明返回值的名称function test1() public view returns(uint result){result = 1;return result;  //如果不写这条语句也是可以的,因为有声明过返回值的名称(但不建议搞花里胡哨)}//可以返回任意匹配类型的值(类型必须匹配,名称不匹配没关系)function test2() public view returns(uint result){ uint a = 10;result = 100;return a;}//可以返回多个参数,在声明了返回值名称的情况下可以不用写return语句,但必须要给返回值赋值function test3(uint a,uint b) public view returns(uint add,uint multiply){add = a+b;multiply = a*b;}//返回多个参数时return语句要加括号function test4(uint a,uint b) public view returns(uint add,uint  multiply){return (a+b,a*b);}//可以利用多返回值的特性直接进行数据交换操作function test5(uint a,uint b) public view returns(uint _b, uint _a){return (b,a);}}

4、变量的生命周期与作用域:

(1)作用域:在程序中有非常多的花括号,变量定义在哪对花括号中,那么这对花括号所包含的就是变量的作用域,变量可以在其作用域内有效使用。(注意,函数形参的作用域是函数内部,虽然它看起来不是定义在函数体内部)

(2)生命周期:从变量被分配空间到空间被收回的这一个时间段,称为变量的生命周期,变量的生命周期自其被定义开始,至其作用域尾部结束(没有进行手动销毁的话)。

5、值传递与副本拷贝:

pragma solidity ^0.5.17;contract transferValueTest
{uint public a = 200;uint public b = a;   //将a的值赋给b,但是a和b各自占有不同的空间function changIt() public{b = 400;  //改变b的值,并不影响a}//i作为形式参数,当调用该函数时,是将所传值的副本传入的,并不会改变所传引用的值,也就是说,对i做修改并不影响a的值function changeIt3(uint i) public returns(uint){i++;return i++;}function test() public {changeIt3(a);}}

6、const静态修饰:

pragma solidity ^0.5.17;contract constantTest
{// 在0.4版本中,constant等同于view,在0.5以上的版本中已经废弃/*function test() public constant returns(uint){return 100;}*/
}

7、构造函数:

pragma solidity ^0.5.17;contract constructorTest
{//初始化结果为0uint public a;//构造函数的名称与合约名相同,在合约部署(或者被创建)的时候执行(0.5以下版本支持该种语法)/*function constructorTest(){a = 100;}*///一个合约内部不能有多个构造函数/*function constructorTest(uint _a,uint _b){a = _a;}*///在0.5以上版本中,solidity采用了关键字constructor来定义构造函数constructor() public{a = 100;}/*address public ower;function constructorTest()  在合约部署时,可以借助构造函数传递一些内容到合约内,例如部署合约的账户{ower = msg.sender;}*/
}

8、函数修改器modifire:

(1)基本用法:

pragma solidity ^0.5.17;contract modifireTest
{address public ower;uint public num = 0;constructor() public{ower = msg.sender;}//定义一个函数修改器 modifier onlyOwer{require(msg.sender == ower);  //不符合条件时则抛出异常,停止执行下面的语句并回滚//修饰函数时,函数相当于被插入到'_;'位置,然后把onlyOwer当作函数执行_;}function changeIt(uint _num) public onlyOwer{num = _num;  //该例中只有部署该合约的账户才有权利调用这个函数,其它账户调用该函数将会报错//当然,“require(msg.sender == ower);”也可以直接写在该函数中,这样就不需要借助modifier}}

Solidity的异常处理:

①Solidity使用“状态恢复异常”来处理异常。这样的异常将撤消对当前调用(及其所有子调用)中的状态所做的所有更改,并且向调用者返回错误。

②函数assert和require可用于判断条件,并在不满足条件时抛出异常

• assert() 一般只应用于测试内部错误,并检查常量

• require() 应用于确保满足有效条件,或验证调用外部合约的返回值

• revert() 用于抛出异常,它可以标记一个错误并将当前调用回退

(2)运用示例1:

pragma solidity ^0.5.17;contract mappingTest
{//一个钱包地址对应一个个人身份id mapping(address => uint) idMapping;//一个人的身份id地址对应一个人的姓名mapping(uint => string) nameMapping;uint id = 0;address public ower;//定义一个函数修改器 modifier onlyOwer{require(idMapping[msg.sender] == 0);  //判断调用函数的账户有没有绑定身份的记录,以免同一账户注册多个身份//修饰函数时,函数相当于被插入到'_;'位置,然后把onlyOwer当作函数执行_;}function register(string memory name) public onlyOwer //该函数模拟新账户绑定身份{address account = msg.sender;  //调用该函数的账户为需要绑定身份和生成id号的新账户id++;  //这里的id号应该是随机生成,总之每个调用该函数的账户都应该获得不同的id号//给账户分配一个ididMapping[account] = id;//再将个人id与个人姓名进行映射绑定nameMapping[id] = name; }//根据账户地址获取idfunction getIdByAddress(address account) public view returns(uint){return idMapping[account];}//根据id获取个人姓名function getNameById(uint id) public view returns(string memory){return nameMapping[id];}

(3)运用示例2:

pragma solidity ^0.5.17;contract modifireTest
{uint level = 200;uint money = 0;modifier modifyLevel(uint _inputLevel)  //函数修改器可以有参数,这样使用起来更加灵活{require(level >= _inputLevel, "Your level is not within the range!");//如不满足require中的条件,错误类型为Your level is not within the range_;}function addMoney() modifyLevel(50) public {//require(level >= 50);  五十级以上才能调用该函数money = 100;}function recoverCash() modifyLevel(200) public {//require(level >= 200);  两百级以上才能调用该函数money = 200;}function getMoney() public view returns(uint) {return money;}}

(4)多重modifire的执行顺序:

pragma solidity ^0.5.17;contract modifireTest4
{uint public a = 0;modifier mod1{a = 1;  //执行顺序——1(最先执行)_;a = 2;  //执行顺序——5(最后执行)}modifier mod2{a = 3;  //执行顺序——2_;a = 4;  //执行顺序——4}function test() public mod1 mod2  //调用该函数后,a的值为2{a = 100;  //执行顺序——3}}

9、合约的继承:

(1)基本的继承:

pragma solidity ^0.5.17;contract Father
{uint money = 10000;function noSmoking() public view returns(string memory){return "I'm not somking";}
}contract Son is Father  //继承语法:contract 子类名称 is 父类名称1,父类名称2……
{function getMoney() public view returns(uint){return money;  //子类继承了父类中的属性
}function test() public view returns(string memory){return noSmoking();  //子类继承了父类中的函数}
}

(2)连续继承:

pragma solidity ^0.5.17;contract GrandFather
{uint height = 170;
}contract Father is GrandFather
{uint money = 10000;function getHeight() public view returns(uint){return height;  //子类继承了父类中的属性}
}contract Son is Father
{function getHeight() public view returns(uint){return height;  //子类继承了父类的父类中的属性}
}

(3)继承权限:

①合约属性的继承:

pragma solidity ^0.5.17;contract Father
{uint private privateMoney = 2000;  //加上private标识的属性或函数不会被子类继承//其余情况下可以被继承//uint privateMoney = 2000;//uint public privateMoney = 2000;//uint internal privateMoney = 2000;//注意:external不能修饰属性,只修饰函数uint money = 10000;function noSmoking() public view returns(string memory){return "I'm not somking";}}contract Son is Father
{function getMoney() public view returns(uint){return money;  //正常“财产”可以被继承
}function getPrivateMoney() public view returns(uint){//return privateMoney;  父类的私房钱子类无法继承
}}

②public修饰父类函数:

pragma solidity ^0.5.17;contract Father
{function noSmoking() public view returns(string memory){return "I'm not somking";}}contract Son is Father
{function test() public view returns(string memory){return noSmoking();  //子合约可以正常调用父类中public修饰的函数}}

③private修饰父类函数:

pragma solidity ^0.5.17;contract Father
{function noSmoking() private view returns(string memory){return "I'm not somking";}}contract Son is Father
{function test() public view returns(string memory){//return noSmoking();  子合约不可以调用父类中private修饰的函数}}

④internal修饰父类函数:

pragma solidity ^0.5.17;contract Father
{function noSmoking() internal pure returns(string memory){return "I'm not somking";
}function test() public returns(string memory){return noSmoking();  //被internal修饰的函数,只能在合约内部以及子合约中被调用,外部无法直接调用}}contract Son is Father
{function test2() public pure returns(string memory){return noSmoking();  //子合约可以正常调用父类中internal修饰的函数(当然,也只能在合约内部调用,外部不可见)}}

⑤external修饰父类函数:

pragma solidity ^0.5.17;contract Father
{function noSmoking() external pure returns(string memory){return "I'm not somking";}function test() public returns(string memory){//return noSmoking();  被external修饰的函数,只能在外部被调用,合约内部以及子合约中无法直接调用return this.noSmoking();  //通过this可以让编译器认为这是在外部通过该合约地址调用该函数,这样就不会报错}}contract Son is Father
{function test2() public view returns(string memory)  //使用this的话,千万不要使用pure{//return noSmoking();return this.noSmoking();  //子类也可以通过this调用父类中external修饰的函数}}contract Mother
{function test() public returns(string memory){Father f = new Father();  //对于被external修饰的函数,在其它非子合约中可以直接创建合约对象,通过合约对象进行外部调用return f.noSmoking();}}

10、全局变量自动getter函数:

(1)普通变量的get方法:

pragma solidity ^0.5.17;contract GetterTest
{uint public num = 100;  //public修饰符修饰的属性,默认会生成一个get方法,供我们外部调用/*function num() external returns(uint)  {return num;}1、变量用public修饰后,这个函数就是生成的get方法(函数体内部定义的变量不能用public修饰)2、默认生成的get函数是external权限的,不能够在合约的内部调用3、对于该例,num()方法只能有一个,要是自己进行重写,就会覆盖默认生成的get方法*/function test() public{// num();this.num();  //可以通过this对get方法进行外部调用}}

(2)mapping类型数据的get方法:

pragma solidity ^0.4.18;  //编译器版本与前面例子所用的不同contract GetterTest
{mapping(uint => string) public map;function map(uint key) external returns(string)  //map的get方法(需传入key值才能获取value值,对于嵌套的mapping,就需要传入多个key值){return map[key];}}

补充——mapping映射:

pragma solidity ^0.5.17;contract mappingTest
{//个人认为这个有点像Python中的字典(可以理解为mapping(key => value) 字典名)//一个钱包地址对应一个个人身份id mapping(address => uint) idMapping;//一个人的身份id地址对应一个人的姓名mapping(uint => string) nameMapping;uint id = 0;function register(string memory name) public //该函数模拟新账户绑定身份{address account = msg.sender;  //调用该函数的账户为需要绑定身份和生成id号的新账户id++;  //这里的id号应该是随机生成,总之每个调用该函数的账户都应该获得不同的id号//给账户分配一个ididMapping[account] = id;//再将个人id与个人姓名进行映射绑定nameMapping[id] = name;        }//根据账户地址获取idfunction getIdByAddress(address account) public view returns(uint){return idMapping[account];}//根据id获取个人姓名function getNameById(uint id) public view returns(string memory){return nameMapping[id];
}mapping(uint => mapping(uint => mapping(uint => string))) public map;function test() public{map[0][1][1] = "lalalalala";  //mapping数据类型还可以嵌套,相当于Python中的多维字典//map[0]:mapping(uint => mapping(uint => string))//map[0][1]:mapping(uint => string)//map[0][1][1]:string}}

mapping(key => value) Mapping的相关语句:

(1)“mapping(type1 => type2) Mapping;”的作用是创建一个type1类型到type2类型的映射,映射组的名称为“Mapping”。

(2)“Mapping[key] = value;”的作用是:

①如果Mapping组中此前没有key这个键值,那么Mapping组中会添加key这个键值到value的映射。

②如果Mapping组中此前存在key这个键值,那么key键值的映射修改为value。

11、继承中的重写:

(1)属性重写:

pragma solidity ^0.5.17;contract Father
{uint money = 10000;uint public height = 170;  //父类属性用public修饰,那么子类继承后会生成get方法,调用该方法会获取父类的height而不是子类的}contract Son is Father
{uint money = 20000;  //子类重写了父类的money,以子类为准(但是不影响父类的money)uint height = 180;  //子类重写了父类的height,那么子类使用height时将以此为准(如果用public修饰该属性,那么此处生成的get方法会将父类生成的get方法覆盖,调用该方法会获取子类的height)function getMoney() public view returns(uint){return money;}function getHeight() public view returns(uint){return height;
}}

(2)函数重写:

pragma solidity ^0.5.17;contract Father
{uint public money = 10000;function noSmoking() public view returns(string memory){return "I don't smoke,and I do not drink";}
}contract Son is Father
{uint public money = 20000;function noSmoking() public view returns(string memory)  //子类重写了父类的函数,父类函数将会被覆盖{return "I do not smoke,but I do drink";}function test() public view returns(string memory){return noSmoking();}
}

12、多继承需要注意的情况:

pragma solidity ^0.5.17;contract Father
{uint public money = 10000;uint public height = 180;}contract Mother
{uint public money = 20000;uint public height  = 170;uint public weight = 120;}contract Son is Father,Mother
{function test() public view returns(uint){return height;  //会返回Mother中的height,后继承的属性如果与前面继承的相同,前继承的属性将会被覆盖}}

13、合约的销毁(析构函数):

pragma solidity ^0.5.17;contract DestructTest
{address ower;constructor() public{ower = msg.sender;}uint public money = 100;function increment() public{money += 100;}function kill() public{if(msg.sender == ower)  //只有发布合约的账户有权利销毁合约{//手动进行自我销毁selfdestruct(msg.sender);}}    
}

相关文章:

基于以太坊的智能合约开发Solidity(函数继承篇)

参考教程:【实战篇】1、函数重载_哔哩哔哩_bilibili 1、函数重载: pragma solidity ^0.5.17;contract overLoadTest {//不带参数function test() public{}//带一个参数function test(address account) public{}//参数类型不同,虽然uint160可…...

【论文极速读】LVM,视觉大模型的GPT时刻?

【论文极速读】LVM,视觉大模型的GPT时刻? FesianXu 20231210 at Baidu Search Team 前言 这一周,LVM在arxiv上刚挂出不久,就被众多自媒体宣传为『视觉大模型的GPT时刻』,笔者抱着强烈的好奇心,在繁忙工作之…...

TS基础语法

前言: 因为在写前端的时候,发现很多UI组件的语法都已经开始使用TS语法,不学习TS根本看不到懂,所以简单的学一下TS语法。为了看UI组件的简单代码,不至于一脸懵。 一、安装node 对于windows来讲,node版本高…...

【基于NLP的微博情感分析:从数据爬取到情感洞察】

基于NLP的微博情感分析:从数据爬取到情感洞察 背景数据集技术选型功能实现创新点 今天我将分享一个基于NLP的微博情感分析项目,通过Python技术、NLP模型和Flask框架,对微博数据进行清洗、分词、可视化,并利用NLP和贝叶斯进行情感分…...

Ubuntu 18.04使用Qemu和GDB搭建运行内核的环境

安装busybox 参考博客: 使用GDBQEMU调试Linux内核环境搭建 一文教你如何使用GDBQemu调试Linux内核 ubuntu22.04搭建qemu环境测试内核 交叉编译busybox 编译busybox出现Library m is needed, can’t exclude it (yet)的解释 S3C2440 制作最新busybox文件系统 https:…...

GEE——利用Landsat系列数据集进行1984-2023EVI指数趋势分析

简介: 利用Landsat系列数据集进行1984-2023EVI指数趋势分析其主要目的是进行长时序的分析,这里我们选用EVI指数,然后进行了4个月的分析,查看其最后的线性趋势以及分布状况。 EVI指数: EVI指数(Enhanced Vegetation Index,增强型植被指数)是一种反映植被生长状态的遥…...

JAVA安全之Spring参数绑定漏洞CVE-2022-22965

前言 在介绍这个漏洞前,介绍下在spring下的参数绑定 在Spring框架中,参数绑定是一种常见的操作,用于将HTTP请求的参数值绑定到Controller方法的参数上。下面是一些示例,展示了如何在Spring中进行参数绑定: 示例1&am…...

辨析旅行商问题(TSP)与车辆路径问题(VRP)

目录 前言旅行商问题 (TSP)问题介绍数学模型符号定义问题输入约束条件目标函数问题输出 解的空间解空间大小计算解释 车辆路径问题 (VRP)问题介绍TSP到VRP的过渡数学模型符号定义问题输入约束条件优化目标问题输出 解空间特殊情况一般情况 TSP 与 VRP 对比 前言 计划是通过本文…...

2024年JAVA招聘行情如何?

大家都在说Java求职不好找,是真的吗?我们来看看数据。 数据支持:根据TIOBE 5月份的编程语言排行榜,Java仍然是前三名之一。这意味着,Java在开发领域仍然占据重要地位。 而在中国的IT市场中,Java仍然是主要…...

【合集】SpringBoot——Spring,SpringBoot,SpringCloud相关的博客文章合集

前言 本篇博客是spring相关的博客文章合集,内容涵盖Spring,SpringBoot,SpringCloud相关的知识,包括了基础的内容,比如核心容器,springMVC,Data Access;也包括Spring进阶的相关知识&…...

yolov5 获取漏检图片脚本

yolov5 获取漏检图片脚本 获取样本分数在0.05到0.38直接的样本。 # YOLOv5 by Ultralytics, GPL-3.0 licenseimport argparse import json import os import sys import time from pathlib import Pathimport cv2 import numpy as np import torch import torch.backends.cud…...

Unity之OpenXR+XR Interaction Toolkit接入微软VR设备Windows Mixed Reality

前言 Windows Mixed Reality 是 Microsoft 用于增强和虚拟现实体验的VR设备,如下图所示: 在国内,它的使用率很低,一把都是国外使用,所以适配起来是相当费劲。 这台VR设备只能用于串流Windows,启动后,会自动连接Window的Mixed Reality程序,然后打开微软的增强现实门户…...

【小聆送书第二期】人工智能时代AIGC重塑教育

🌈个人主页:聆风吟 🔥系列专栏:网络奇遇记、数据结构 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 📋正文📝活动参与规则 参与活动方式文末详见。 📋正文 AI正迅猛地…...

中国移动公网IP申请过程

一、动机 由于从事互联网行业10年,一直从事移动端(前端)开发工作,未曾深入了解过后端技术,以至于工作10年也不算进入互联网的门。 所以准备在自己家用设备上搭建各种场景的服务器(云服务对个人来说成本偏…...

动态获取绝对路径

在Python中,可以使用 os模块 来获取当前工作目录的路径,并使用 os.path.join()函数 将相对路径与当前工作目录结合起来,形成一个动态获取的绝对路径 以下是一个简单的例子: import os# 获取当前工作目录的路径 current_director…...

pytorch中的归一化:BatchNorm、LayerNorm 和 GroupNorm

1 归一化概述 训练深度神经网络是一项具有挑战性的任务。 多年来,研究人员提出了不同的方法来加速和稳定学习过程。 归一化是一种被证明在这方面非常有效的技术。 1.1 为什么要归一化 数据的归一化操作是数据处理的一项基础性工作,在一些实际问题中&am…...

RocketMq源码分析(九)--顺序消息

文章目录 一、顺序消息二、顺序消息消费过程1、消息队列负载2、消息拉取3、消息消费4、消息进度存储 三、总结 一、顺序消息 RocketMq在同一个队列中可以保证消息被顺序消费,所以如果要做到消息顺序消费,可以将消费主题(topic)设置…...

Windows下nginx的启动,重启,关闭等功能bat脚本

echo off rem 提供Windows下nginx的启动,重启,关闭功能echo begincls ::ngxin 所在的盘符 set NGINX_PATHG:::nginx 所在目录 set NGINX_DIRG:\projects\nginx-1.24.0\ color 0a TITLE Nginx 管理程序增强版CLSecho. echo. ** Nginx 管理程序 *** echo.…...

Python 字典:dic = {} 和 dic = defaultdict(list)之间的区别

d defaultdict(list) 和 d {} 在Python中代表了两种不同类型的字典初始化方式,它们之间有几个关键的区别: 1、类型 d defaultdict(list):这里使用的是 collections 模块中的 defaultdict 类。它是一个字典的子类,提供了一个默…...

绘图 Seaborn 10个示例

绘图 Seaborn 是什么安装使用显示中文及负号散点图箱线图小提琴图堆叠柱状图分面绘图分类散点图热力图成对关系图线图直方图 是什么 Seaborn 是一个Python数据可视化库,它基于Matplotlib。Seaborn提供了高级的绘图接口,可以用来绘制各种统计图形&#xf…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

<6>-MySQL表的增删查改

目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表&#xf…...

大话软工笔记—需求分析概述

需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...