在日常的程序编写中,我们可能会遇到这样的需求!就是让一个方法,返回多个值,或者多种类型的值!
这类问题其实比较好解决,方案有很多种!本次讲解下,在C#语言中,此类问题的解决方案!
如果长期从事C#语言开发工作的小伙伴们,对于这两个关键字,肯定再熟悉不过了!
在这里温故而知新一波儿,为了新入坑的小伙伴们着想一下!
ref关键字( Reference的缩写 ): “The ref keyword indicates a value that is passed by reference” 顾名思义就是通过引用来传递参数。
接下来看下ref关键字的用法:
out关键字:“As a parameter modifier, which lets you pass an argument to a method by reference rather than by value”参数修饰符,允许您通过引用而不是通过值将参数传递给方法。
接下来看下out关键字的用法:
ref与out关键字,总结一下:
实际上无论是ref,还是out,作用都是将值类型按引用类型传递,都是服务于值类型的关键字。
他们的区别是:ref关键字要求,参数必须先初始化,方法内可以不用对ref修饰参数赋值 *** 作。而out关键字则要求,参数可以不初始化,但方法内必须存在out修饰参数的赋值 *** 作。
究其原因:out关键字是在方法内,完成分配内存地址 *** 作。而ref则是将地址传入到方法中。
ref关键字使用错误的案例:
out关键字使用错误案例:
C#进入到异步时代,异步多线程编程模型,在如今的NET技术体系中,可以说遍地开花般的存在。
这种异步编程模型,也让NET CORE有了更优秀的性能,无论是吞吐量,还是程序执行性能,都有了质的飞跃。
回顾下异步方法定义三部曲:
1:async后缀,见名知意。
2:返回类型只能为void、Task、Task ,推荐2、3。
3:参数不能用out、ref关键字修饰。
此时的 “小麻烦” 来了,异步虽好,但是无法使用上述讲到的两个关键字,实现方法的多返回值 *** 作,只能说有一些尴尬了!
但静心一想,这两个关键字与异步的本质存在严重的分歧。因为异步不会阻塞主线程,接受请求后,让出线程忙自己的事情了,后续的任务由上下文进行关联,将结果返回给当初的请求者。
所以out与ref这两个关键字,在这个场景明显是不适用的。
不过我们此时可以通过元组来完美解决这个问题,在NET Framework 40版本,元组与Task一起更新到版本之中,可见官方给出的技术方案是完全配套的。
元组犹如你的抽屉一般,什么乱七八糟的,都可以往里扔。接下来我们详细的学习下,元组系列知识,Tuple与ValueTuple。
Tuple:元组支持1到7个元组元素,如果有8个元素或者更多,需要使用Tuple的嵌套与Rest属性去实现。元组中的项,默认为item1到item7,这个key的名字为默认分配的,无法自定义改变!(这个也是元组与集合、字典不同的地方)
元组嵌套案例:
定义元组案例(典型分页方法,分页需要一个数据源,一个总数):
小伙伴们,目前我们已经掌握了Tuple元组的基本使用方式,是不是很方便啊!接下来继续学习下ValueTuple的使用方式,感受下性能版元组的魅力所在。
ValueTuple 是C# 70推出的,Tuple是类,引用类型的。而ValueTuple是枚举类型,为值类型。所以从资源消耗角度来说,ValueTuple更优秀一些。
另外ValueTuple允许是支持读写 *** 作的,可以修改项的内容。ValueTuple同时还支持匿名写法,从编程角度,也优化了一波儿。
匿名方法写法:
转换成JSON格式案例:
老夫一口气终于写完了!觉觉去喽!
喜欢的小伙伴可以关注我,一起交流学习!我是IT鸟叔,一位喜欢写程序、钓鱼、喝茶、玩 游戏 的中年大叔!
在Matlab下输入:edit,然后将下面两行百分号之间的内容,复制进去,保存
function [sinx,cosx]=myfun_1(x)
sinx=sin(x);
cosx=cos(x);
返回Matlab输入:
x=0:1:2pi;
[sx,cs]=myfun_1(x)
扩展资料
clc
clear
%定义xx,yy矩阵大小
m=3;
n=1;
xx=zeros(m,n);
yy=zeros(m,n);
%初始化xx
xx=init_x(xx,m,n);
%将xx矩阵赋值给yy
yy=function_1(xx,yy,m,n)
function x=init_x(x,m,n)
for i=1:m
for j=1:n
x(i,j)=randsample(20,1);
end
end
参考资料:
1 建立数组,返回指针。
在要返回的两个值类型相同时,可以用创建数组的方式,将要返回的值存在数组中,并返回数组首地址,这样就可以实现返回两个值的效果。
需要注意的是,要返回数组首地址,那么返回的值不可以是局部变量,有如下几种是可以的:
a) 使用静态局部变量存储,并返回地址;
b) 使用全局变量存储,返回地址;
c) 函数中动态分配内存,并返回申请到的地址,此种方法需要注意,在使用后需要释放;
d) 在参数中传入数组地址,并返回。即返回的实际上是主调函数中的变量地址。
2 建立结构体,返回结构体变量。
将需要返回的值,写成结构体形式,并返回结构体变量,这样可以实现一个返回值中含有多组数据。
3 当数据规模较小时,可以采用将小规模数据合并为大规模数据的方式,进行返回。
比如,需要返回两个char型数据时,可以通过返回一个short数据,高地位分别存储各自的值。
除以上方法外,还可以不使用返回值的方式,而是通过函数参数传值,或者全局变量传值等方式,将要返回的值回传给主调函数。做一个表格有父母姓名和子女姓名,
例如张三 男,张四 男,返回值“父子”。
父母和子女都有两个情况:“男”“女”,
返回值就有四个结果“父子”“父女”“母子”“母女”。
这个函数可以如下表达:
=IF(AND(C536="男",I536="男"),"父子",
IF(AND(C536="男",I536="女"),"父女",
IF(AND(C536="女",I536="男"),"母子",
IF(AND(C536="女",I536="女"),"母女",""))))
最开始说一下我使用的解决办法:Pair 和 Triple
偶然看到这个问题,浏览量也很大,还是写一下我认为最好的办法吧,跟大家交流一下。
说一下前面的人答的方案,都可以解决问题,但是觉得不太好。您要是说 可以解决问题就行,那我无话可说。写代码如果只是为了完成任务,不考虑实现是否优雅 和咸鱼有什么区别呢。
数组明显不合适,数组适合放同一类型的数据,当然,你可以使用List<Object>,用Object 放结果,调用方需要知道Object的实际类型并做强制转换,不够优雅,差评
Map<String,Object> 是一种能解决问题的做法,使用Object 来放结果也存在调用方需要知道其实际类型并做强转的问题,用key 作区分,方法调用者需要知道方法内部的key ,即使使用全局变量做key 也不够优雅
自定义对象,新建一个类,例如 public class DoubleResult<A, B>{getter; allArgsConstructor;}、public class TripleResult<A, B, C>{getter; allArgsConstructor;
} ,效果棒棒的
接下来要说的 Pair 和Triple 就是上面第三种方案的实现。orgapachecommonslang3tuplePair,orgapachecommonslang3tupleTriple 是commons-lang包里的两种元组类型。Pair<L,R>可以存两个数据,Triple<L,M,R> 可以存三个,再多 那么考虑一下你的方法是否可以拆一下。
简单说一下他们的用法吧。
Pair 初始化:
例:Pairof("a","b");
或:
Pair<Object,Object> pair = new Pair<Object, Object>() {@Override
public Object getLeft() {
return null;
}
@Override
public Object getRight() {
return null;
}
@Override
public Object setValue(Object value) {
return null;
}
};
Triple 初始化:
或:
@Override
public Object getLeft() {
return null;
}
@Override
public Object getMiddle() {
return null;
}
@Override
public Object getRight() {
return null;
}
};
Pair 获取内容:
pairgetKey();pairgetValue();
Triple 获取内容:
triplegetMiddle();
triplegetRight();
另外orgapachecommonslang3tuple 包下还有ImmutablePair、ImmutableTriple、MutablePair、MutableTriple 分别对应两种结构的不可变和可变类型,大家可以自行探索。
具体的实现方法可以参考如下程序:
%% 函数fun的功能是返回变量a,b的最大最小值
function [maxValue, minValue] = fun(a, b) % 多返回值(用中括号括起来就可以实现多返回值)
if a > b
maxValue = a;
minValue = b;
else
maxValue = b;
minValue = a;
endjava中每个方法的返回值,有且仅有一个,因为方法中一旦使用return语句返回返回值,整个方法就会结束,下面的语句也将不会执行。
java中如果想返回多个值的话,可以采用数组和集合进行存储,然后返回集合或者数组即可。其中数组用来封装基本数据类型的数据,集合用来封装对象数据。可以根据返回值的实际类型来选择容器。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)