首页 > 软件 > 如果函数的某个参数设置了默认值,则无论何时调用次函数,该参数的值永远不变

如果函数的某个参数设置了默认值,则无论何时调用次函数,该参数的值永远不变

软件 2024-07-07

听说UiBot支持C++语言扩展,具体要怎么操作?

UiBot本身的部分代码就是基于微软的.Net框架,用C#语言编写的。所以,也可以用C#语言编写UiBot的插件(以下简称为.Net插件)。实际上,微软的.Net框架支持多种编程语言,包括VB.Net、C++/CLI等等,这些编程语言都遵循.Net框架的规范,它们都可以用来编写.Net插件,但因为C#是微软主推的编程语言,所以本文用C#举例,有经验的读者亦可将其移植到.Net框架上的其他语言。另外,UiBot对.Net插件的支持也是在不断升级的,本文以UiBot Creator 5.1版为例,如果在老版本的UiBot上,一些例子可能无法正常运行,请及时升级。

为了方便您用C#语言写.Net插件,我们设计了一个插件的模板,并将其源码放在GitHub上,点击这里即可获取。如果您习惯使用git,也可以从这个URL拉取:https://github.com/Laiye-UiBot/extend-example。建议您在写.Net插件的时候,直接在这个模板的基础上写,而无需从头开始。后续讲述的内容,也将围绕这个模板中的例子展开。

和Java插件类似,.Net插件也需要编译成扩展名为.dll的文件,才能被UiBot使用。微软的集成开发环境Visual Studio兼具编写和编译的功能,并且也提供了免费的社区版,推荐下载使用。我们提供的模板是基于Visual Studio 2015版本的,您可以选择这个版本,也可以选更高版本的Visual Studio,但不建议使用低于2015版本的Visual Studio。

安装了Visual Studio,并下载了我们的.Net插件模板后,可以双击UiBotPlugin.sln文件,这是一个“解决方案”,名字起得很唬人,实际上就是多个相关联的文件的集合。用Visual Studio打开这个解决方案后。可以看到,里面包含了很多内容,其中唯一需要我们动手修改的是UiBotPlugin.cs文件,其他的文件、引用、Properties等都可以不去动。如下图:

.Net插件的模板

在UiBotPlugin.cs文件里,有一个叫UiBotPlugin的命名空间,其中包含了一个接口(interface)和一个类(class)。为了避免混淆,我们推荐把这个命名空间的名字改为您的插件名。比如最终的插件文件是DotNetPlugin.dll,那么插件名就是DotNetPlugin,这个命名空间的名字也改为DotNetPlugin为宜。

从模板中可以看出:在接口里面声明了三个函数,在类里面写了这三个函数的实现。这三个函数都是例子,您随时可以把它们的声明和实现都删掉,加入您自己的插件函数。但请特别注意:在加入函数的时候,也要保持类似的写法,需要在接口中声明,在类中实现,否则,UiBot不能正常识别这个插件函数。

我们用例子中的Add函数为例,尝试编译插件,并在UiBot中调用这个函数:

  • 选择Visual Studio的“生成”(Build)菜单项,编译这个解决方案之后,会看到在插件的目录下有个叫Release的目录,里面产生了一个叫UiBotPlugin.dll的文件。

  • 把这个文件手动改名为您的插件名,并保留.dll的扩展名。如改名为DotNetPlugin.dll。

  • 把这个文件放到UiBot的extend/DotNet目录下。

  • 打开UiBot,新建一个流程,在源代码视图写入代码:

  • Traceprint DotNetPlugin.add(1, 1)

  • 运行此流程,结果如下所示,代表插件调用正常。

  • .Net插件运行结果
  • 您可能注意到了,在前面的Python插件、Java插件的例子中,都有Add这个例子函数,而除了插件名之外,UiBot调用它们的方式和运行结果都没有区别。实际上,不同的插件内部实现是有很大差异的,比如在Python语言里,默认用UTF-8编码来保存字符串,而在.Net里默认用UTF-16保存。但UiBot已经帮您抹平了这些差异,让您在使用的过程中不必关心这些细节。

    9.3.2插件API

    和Python、Java插件类似,在.Net插件中,也可以使用插件API,反过来调用UiBot的一部分功能。如果要调用插件API,只需要基于UiBot提供的模板编写插件即可,无需做其他任何设置。

    .Net插件中能使用的插件API的名字、参数和含义都和Java插件完全一致,例如,可以用UiBot.API.IsStop()来检测当前流程是否需要马上停下来,等等。请参考Java插件的中关于插件API的讲解,不再赘述。

    在模板中,您可能会看到一个名叫DotNetAdapter.dll的文件。实际上,这个文件是UiBot每个版本都包含的。从UiBot 5.1版开始,您调用的.Net版的插件API,实际上都在这个文件里面实现。因此,当您的插件发布的时候,并不需要包含这个文件,因为UiBot已经自带了。

    同时,如果您的UiBot更新到了更高的版本,DotNetAdapter.dll中也可能会包含了更多的插件API。您可以自行从UiBot中拿到新版本的DotNetAdapter.dll文件,并放在您编写的插件的源代码所在的目录下,即可使用到新版的插件API。

    9.3.3变量的传递

    和Java类似,C#.Net也是静态类型的编程语言,变量在使用之前需要先定义,且定义时必须指定变量的类型。而且,数组中通常只能包含同一种类型的数据。这与UiBot的动态类型有很大的不同。

    因此,在编写和使用.Net插件的时候,需要符合以下规定:

  • 对于整数、浮点数、字符串、布尔类型等基本类型的参数,UiBot对.Net插件的类型检查不是很严格,它会尽量进行转换,即使转换不成功,也不会报错。所以,请在使用时特别留意每个参数的类型,避免传入了不正确的值,而没有及时发现。

  • 如果需要把字典或数组类型从UiBot中传到.Net插件中,.Net插件中的参数类型只能使用Newtonsoft.Json.Linq.JArray(对应数组)或者Newtonsoft.Json.Linq.JObject(对应字典)。在模板中,由于我们已经写了using Newtonsoft.Json.Linq;,所以可以省略前缀,简写为JArray(对应数组)或JObject(对应字典),下文亦使用此简化写法。

  • 如果需要把字典或数组类型从.Net插件中传到UiBot中,.Net插件中的返回值类型只能使用JArray(对应数组)或JObject(对应数组)。UiBot会自动把JArray类型的返回值转换成UiBot中的数组,而把 JObject类型的返回值转换成UiBot中的字典。

  • 无论传入参数,还是返回值,这些复合类型在.Net插件和UiBot之间都采用值传递的方式,而不是引用传递的方式。

  • 在插件模板中,有一个作为例子的Concat函数,用于演示如何把两个数组从UiBot传到.Net插件中,又如何把两个数组连接后的结果返回到UiBot中。建议读者仔细阅读。

    9.3.4插件的引用模块

    UiBot本身是依赖于.Net Framework的,并且假设用户已经安装了.Net Framework 4.5.2(含)以上的版本。如果没有安装.Net Framework,或者版本不对,UiBot本身都不能运行,当然就更不能使用您编写的插件了。所以,在编写插件的时候,只要您的插件依赖的也是.Net Framework 4.5.2版本,就不必担心环境不匹配的问题。

    微软已经在.Net Framework里面内置了非常丰富的功能,但难免有的功能仍然没有包含,需要引用第三方的.Net dll文件。

    和Java插件类似,UiBot在加载一个.Net插件的时候,如果这个.Net插件引用了其他第三方的.Net dll文件,UiBot首先会试图到.Net插件所在的目录下去搜索被引用的dll文件。如果没有找到,还会再到<插件名>.lib这个目录下去找一次。比如,我们有个.Net插件,名为A.dll,放置在extend/DotNet目录中,且引用了B.dll。那么UiBot会先尝试找extend/DotNet/B.dll,再尝试找extend/DotNet/A.lib/B.dll。如果这两个目录下都没有找到,会抛出异常。

    9.3.5其他注意事项

  • JArray和JObject并不是.Net Framework里面自带的,而是使用了开源的Json.Net。在编译和运行的时候,都需要依赖一个名为Newtonsoft.Json.dll的文件。 在UiBot提供的模板中,已经包含了这个文件。同时,在每个版本的UiBot中,也会自带这个文件。因此,您可以直接使用JArray和JObject,而并不需要把这个文件包含在插件当中。

  • 在编译插件的时候,编译器可能会警告“DotNetAdapter的处理器架构不匹配”之类的信息。实际上没有影响,无需理睬这个警告。

  • .Net插件中的函数支持默认参数。在调用时,如果某些参数有默认值,则可以不传值,此参数会自动取默认值。

  • 可以在.Net插件的函数中抛出异常,异常可以由.Net插件自行捕获,也可以不捕获。如果.Net插件不捕获,那么异常会自动被传到UiBot中,UiBot可以捕获。 如果UiBot也不捕获,那么流程的运行会出错退出,并且会在出错信息中说明是由于.Net插件中的异常导致的,以便排查问题。

  • .Net中的变量、函数都是区分大小写的,但在UiBot中使用.Net插件时,仍然可以不区分大小写的调用其中的函数。比如,在前面的例子中,可以在UiBot中写DotNet.add(1,1),也可以写dotnet.ADD(1,1),其效果完全一样。

c++中的参数问题

这是默认参数,具体如下 1、默认参数的目的 默认参数也称缺省参数,C++可以给函数定义默认参数。 通常,调用函数时,要为函数的每个参数给定对应的实参,但有时需要用相同的实参反复调用该函数,这时,C++可以给该参数定义默认值,默认参数在函数声明中提供。如声明函数 void delay(int loops=1000); 这样,无论何时调用delay()函数,都不用给loops赋值,程序会自动将它当作1000进行处理;当然也可以对其进行赋值。若对其赋值,则按所赋的实参进行运算;若没有赋值,则按指定的默认值进行运算。 例如: delay(2500); // loops设置为2500 delay();

面向对象程序设计 设置了参数默认值后,调用函数的对应实参就必须省略。这句话是正确还是错误呢?

错了, 函数在定义时可以预先声明默认的形参值,调用时如果给出实参,则用实参初始化形参,如果没有给出实参,则采用预先声明的默认形参值。例如: int add(int x=5,y=6){ //声明默认形参值 return x+y; } int main ( ) { add(10,20); // 用实参来初始化形参,实现 10+20 add(10 ); // 形参 X采用实参值 10 ,Y采用默认值6,实现 10+6 add( ) ; // X和Y都采用默认值,分别为5和6,实现 5+6 } 希望对你有帮助。

jQuery怎样向服务器发出get和post请求


这次给大家带来jQuery怎样向服务器发出get和post请求,jQuery向服务器发出get和post请求的注意事项有哪些,下面就是实战案例,一起来看一下。
假设有个网站A,它有一个简单的输入用户名的页面,界面上有两个输入框,第一个输入框包含在一个form表单里用来实现form提交,第二个输入框是单独的、没有包含在form里,下面就用这两个输入框来学习下jQuery的ajax。
1,前端的html和javascript代码
页面html


输入用户名












页面中引入的demo01.js代码,注意此处实现的是一个简单的GET请求。
$(function($) {
$('input[name=submit2]').on('click', function(e) {
let username = '';
if ('' !== (username = $('#user-name2').val())) {
$.ajax({
url: `demo.php?name=${username}`,
dataType: 'json',
method: 'GET',
success: function(data) {
if (data.result == 1) {
$('.box').html(`

你的姓名${username}已成功保存。

`);
}
},
error: function(xhr) {
// 导致出错的原因较多,以后再研究
alert('error:' + JSON.stringify(xhr));
}
})
.done(function(data) {
// 请求成功后要做的工作
console.log('success');
})
.fail(function() {
// 请求失败后要做的工作
console.log('error');
})
.always(function() {
// 不管成功或失败都要做的工作
console.log('complete');
});
}
});
});jQuery的ajax()方法有两种写法,分别是: $.ajax(url [, settings]); 和 $.ajax([settings]); 两种写法都可以,感觉第一种方法适合用于参数较少的情况,比如,如果只是对一个url做一个简单的请求,不对返回的数据、格式和错误有要求,只需要传递一个url参数就可以,那就可以用第一种写法。上面的demo01.js中采用的是第二种写法,下面解释下参数和相关的函数。
(1)上面代码中ajax()的参数
可以看到这里的参数类型都是javascript对象,即都是 o = {key: value}; 这种类型的数据。jQuery的文档中规定了,这里的参数只能是PlainObject(对象类型的对象),不能是null、自定义的数组、或者像docement这种归属于某种执行环境(比如浏览器)属于某种类型的对象。这里不太好说清楚,可以做个小试验。在命令行里打开node repl,进行下测试:
> node
> typeof(null);
'object'
> typeof([]);
'object'
> typeof(document);
'undefined'
> typeof({});
'object'可以看到null、[](数组类型)、{}(对象类型)都是对象。因为在js中一切皆对象。而在交互式环境中,document则是未定义的一个变量,所以它的类型是undefined。如果在浏览器环境下测试下typeof(document),那么它的类型也是object。下面逐个解释下代码用到的参数:
url,要请求的url地址,它的值应该是包含url的字符串。
dataType,字符串。发出请求后,期望从服务器返回的数据类型。可以指定的类型有xml、html、script、json、jsonp、text。如果不指定,jquery会基于MIME做判断,并会返回一个下面xml、json、script、html当中的一种类型。
method,字符串。HTTP请求方法,默认为GET,上面代码中指定为POST。
success, Type: Function( Anything data, String textStatus, jqXHR jqXHR ) ,匿名函数。HTTP请求成功后要调用的函数,可以传递三个参数给它:从服务器返回的数据(如果上面指定了dataType,则服务器返回的数据类型需要与上面dataType指定的类型一致)、一个可以描述状态的字符串textStatus、还有一个jqXHR对象。可以看到上面只传递了从服务器返回的数据data。
error, Type: Function( jqXHR jqXHR, String textStatus, String errorThrown ) ,匿名函数。HTTP请求失败后要调用的函数,同样也可以传递三个参数。
除了用到的这些参数,还有许多其他的如:async、dataFilter、mimeType等其他参数,不过现在的这个简单的脚本还用不到那么多参数。
(2)“延迟加载函数”
上面代码中 $.ajax().done().fail().always() jqXHR.done()、jqXHR.fail()、jqXHR.always()中分别可以添加deferred对象被解析、被拒绝、被解析或被拒绝这三种情况下的要处理的工作,比如添加个函数什么的。为什么能够这么做呢,这要看$.ajax()返回了什么,它返回的是jqXHR对象(jquery版本大于1.5时)。这个对象实现了Promise interface(Promise机制,用来传递异步操作消息,代表了某个未来才会知道结果的事件)。这就允许在一次请求中添加多个回调函数,甚至可以在请求完成后添加回调函数。
标题“延迟加载”描述的不够准确,但从效果上看是有延迟加载的效果。关于这个问题更详细的解释可以参考jQuery文档中对jqXHR的解释 或一位前端前辈的解释jQuery的deferred对象详解 。
2,后端运行在nginx服务器上的php代码
后端的逻辑很简单:我们把前端获取的数据保存到名为data-demo01的文件中,保存成功则向前端返回一个1作为标志。
(1)前端ajax发起GET请求
如果前端的ajax发起的是一个GET请求,那么后端也比较好处理:
if (isset($_GET['name']) && !empty($_GET['name'])) {
$username = trim($_GET['name']);
if (file_put_contents('data-demo01', $username)) {
echo '{"result": 1}';
}
}(2)前端ajax发起POST请求
js代码中需要修改下ajax()的url、method参数,并增加一个data参数,修改后如下:
// 相同的代码省略
$.ajax({
url: `demo01.php`,
dataType: 'json',
method: 'POST',
data: {"username": username},
// 相同的代码省略因为用POST传递数据,所以去掉url中用来传递数据的参数,下面的data类型要与dataType一致,为json格式,然后将username作为值传递。
那么后端的代码也就可以确定了:
if (isset($_POST['username']) && !empty($_POST['username'])) {
$username = trim($_POST['username']);
if (file_put_contents('data-demo01', $username)) {
echo '{"result": 1}';
}
}如果不出错的话,效果应该是下面这样然后查看下data-demo01,名字果然被保存了。
那么问题来了,如果出错了呢?比如data-demo01文件不可写,或者后台服务器返回的数据格式有错误,或者网络出错。那又该怎么处理呢?我现在也不太清楚,后续再研究吧。
相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!
推荐阅读:
html直接显示JSON方法详解

PHP操作JSON方法大全

countif什么意思

Countif函数是MicrosoftExcel中对指定区域中符合指定条件的单元格计数的一个函数,在WPS,Excel2003和Excel2007等版本中均可使用。

Countif函数应用举例:

1、如图,要计算前面的分数统计表中分数区间在80~89分之间的人数;

2、首先,将光标放在E2单元格之后点击Excel任务栏上面的公式按钮;

3、然后在公式任务栏中点击“插入函数”;

4、在插入函数的页面搜索框输入countif,然后点击选择函数下面的COUNTIF,然后点击页面右下角的确定按钮;

5、在第一个countif函数参数设置页面选定函数计算区域为B2~B11,条件为>=80;

6、然后在第一个countif函数后面输入减号;

7、插入第二个countif函数,第二个countif函数参数设置页面选定函数计算区域为B2~B11,条件为>89,然后点击确定;

8、即可计算出在80~89分区间的人数为5人。


标签:信息技术 CC++ 参数 编程语言 编程

大明白知识网 Copyright © 2020-2022 www.wangpan131.com. Some Rights Reserved. 京ICP备11019930号-18