具有多个输出的 VB 函数 - 结果分配
Posted
技术标签:
【中文标题】具有多个输出的 VB 函数 - 结果分配【英文标题】:VB function with multiple output - assignment of results 【发布时间】:2013-05-02 11:05:25 【问题描述】:我知道VB
中的多个函数分配没有直接的方法,但有我的解决方案 - 好不好,你会如何做得更好?
我需要什么(我在python中如何做,只是一个例子)
def foo(a) ' function with multiple output
return int(a), int(a)+1
FloorOfA, CeilOfA = foo(a) 'now the assignment of results
我如何在 VB 中做到这一点:
Public Function foo(ByVal nA As Integer) As Integer() ' function with multiple output
Return CInt(nA),CInt(nA)+1
End Function
Dim Output As Integer() = foo(nA) 'now the assignment of results
Dim FloorOfA As Integer = Output(0)
Dim CeilOfA As Integer = Output(1)
【问题讨论】:
当nA
已经是Integer
时,没有理由使用CInt(nA)
。
【参考方案1】:
对于未来的读者,VB.NET 2017 及更高版本现在支持将值元组作为一种语言功能。你声明你的函数如下:
Function ColorToHSV(clr As System.Drawing.Color) As (hue As Double, saturation As Double, value As Double)
Dim max As Integer = Math.Max(clr.R, Math.Max(clr.G, clr.B))
Dim min As Integer = Math.Min(clr.R, Math.Min(clr.G, clr.B))
Dim h = clr.GetHue()
Dim s = If((max = 0), 0, 1.0 - (1.0 * min / max))
Dim v = max / 255.0
Return (h, s, v)
End Function
你这样称呼它:
Dim MyHSVColor = ColorToHSV(clr)
MsgBox(MyHSVColor.hue)
注意 VB.NET 如何创建名为 hue
的公共属性,该属性是从被调用函数的返回类型推断出来的。 Intellisense 也适用于这些成员。
但请注意,您需要以 .NET Framework 4.7 为目标才能使其正常工作。或者,您可以在项目中安装 System.ValueTuple
(作为 NuGet 包提供)以利用此功能。
【讨论】:
【参考方案2】:您的解决方案有效,它是返回多个结果的一种优雅方式,但是您也可以尝试使用此方法
Public Sub foo2(ByVal nA As Integer, ByRef a1 As Integer, ByRef a2 As Integer)
a1 = Convert.ToInt32(nA)
a2 = Convert.ToInt32(nA) +1
End Sub
并用
调用foo2(nA, CeilOfA, FloorOfA)
如果您有许多结果要返回,那么考虑一个可以返回所有所需值的类是合乎逻辑的(特别是如果这些值具有不同的数据类型)
Public Class CalcParams
Public p1 As Integer
Public p2 As String
Public p3 As DateTime
Public p4 As List(Of String)
End Class
Public Function foo2(ByVal nA As Integer) As CalcParams
Dim cp = new CalcParams()
cp.p1 = Convert.ToInt32(nA)
.......
Return cp
End Function
【讨论】:
对于这样的基本用途,真的需要实例化一个类吗?也许structure
就够了?
这与返回数组没有太大区别。但是您是对的,只有两个参数和整数类型,您可以使用您的解决方案或通过 Ref 传递预期结果。当您需要处理复杂的数据时,事情会变得更加复杂。这只是一个例子(我承认,有点不太可能)
是的,结构也可以很好地工作。您会有所收获,但这实际上取决于您调用此方法的次数。【参考方案3】:
您使用的方法很好,顺便说一下,您可以将所需的变量作为reference
传递给您的subroutine
,以使您的code
更干净。
Dim FloorOfA As Integer
Dim CeilOfA As Integer
Call foo(10.5, FloorOfA, CeilOfA)
Public Sub foo(ByVal xVal As Integer, ByRef x As Integer, ByRef y As Integer)
x = CInt(xVal)
y = CInt(xVal) + 1
End Sub
【讨论】:
【参考方案4】:也许你可以使用Tuple:
Public Function foo(ByVal nA As Integer) As Tuple(Of Integer,Integer) ' function with multiple output
Return Tuple.Create(CInt(nA),CInt(nA)+1)
End Function
Dim FloorOfA, CeilOfA As Integer
With foo(nA) 'now the assignment of results
FloorOfA =.item1
CeilOfA = .item2
End With
编辑:用 Tuple.Create 替换新的 Tuple(感谢 @mbomb007)
【讨论】:
不知何故我不喜欢它......元组似乎很重,我只需要两个整数。 + 在with
中调用了多少次子程序 foo,一两次?
@Intelligent-Infrastructure:子程序只被调用一次。 'With' 替换了 'Output' 声明。元组允许避免被认为不是很好的做法的 byref 参数。您可以在算法中使用 .item1、.item2,从而避免 FloorOfA,CeilOfA 声明。
我喜欢使用元组,但我不会在这里使用“With”。添加嵌套级别,仅用于访问多个返回结果。我会将结果分配给本地变量。 Dim Output = foo(nA) / Dim FloorOfA = Output.Item1
。像有问题的代码,但使用元组而不是数组。
@ToolmakerSteve:“With”用于避免变量声明的必要性。尤其是在未使用选项推断并且需要完整声明 Dim Output as Tuple(Of Integer,Integer)= foo(nA)
的情况下。我承认这是个人品味的问题。
@IvanH 这就是Tuple.Create()
的用途,因此您不必使用如此冗长的声明。改用它。以上是关于具有多个输出的 VB 函数 - 结果分配的主要内容,如果未能解决你的问题,请参考以下文章