具有多个输出的 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 函数 - 结果分配的主要内容,如果未能解决你的问题,请参考以下文章

如何使用多个输出参数执行存储过程?

vb中 sendmessage WM_char这个API函数 结果无限发

怎么在vb中输出固定小数位数的数字?

vb怎么把结果输出到文本框里?

如何从 Matlab 调用具有多个输出的 C++ 函数?

如果使用func()具有多个输出,如何获得函数输出的长度?