|
' VB.Net 2008+
Public Delegate Function _For_FAdd(Of T)(ByVal a As T, ByVal b As T) As T
Public Delegate Function _For_FElem(Of T)(ByVal i As Integer) As T
Public Shared Function _For(Of T)(ByVal _from As Integer, ByVal _to As Integer, ByVal fAdd As _For_FAdd(Of T), ByVal fElem As _For_FElem(Of T))
If _to < _from Then Throw New Exception()
Dim sum As T
sum = fElem(_from)
For i = _from + 1 To _to
sum = fAdd(sum, fElem(i))
Next i
_For = sum
End Function
数学上面我们常看到这样的符号,比如:
\\&space;\\&space;\\&space;\\&space;\\bigcap_{k=0}^{m}X_{k})
这两个分别是求一串式子的和,和一串的集合的并。
类似地,我们可以从求和、求并,推广到任意的二参数运算(或二参数函数)
比如推广到字符串加

再比如更复杂的,字符串之间以 "," 相连,例如我们要生成一个表示一个数组的字符串,
例如 CStr(x[0]) + "," + CStr(x[1]) + "," + ... + "," + CStr(x[n-1])
\\&space;where\\&space;add\\left&space;(&space;a,b&space;\\right&space;)\\&space;=\\&space;a&plus;","&plus;b)
这个计算,用我们在本文开头定义的 _For 函数可以写成:
_For(0, n-1, Function(a, b) a + "," + b, Function(i) CStr(x(i)))
PS. 有时候考虑到性能,我们还可以有一种变种版本:
Public Delegate Function _For_F(Of T)(ByVal sum As T, ByVal i As Integer) As T
Public Shared Function _For(Of T)(ByVal _from As Integer, ByVal _to As Integer, ByVal sum0 As T, ByVal f As _For_F(Of T))
If _to < _from Then
sum = sum0
Exit Function
End If
Dim sum As T
sum = sum0
For i = _from To _to
sum = f(sum, i)
Next i
_For = sum
End Function
这里的 f 就是上面的 fAdd(求和) 和 fElem(求第i个元素) 的复合函数,
比如上面的那个计算可以改写成:
_For(0, n-1, "", Function(sum, i) sum + "," + CStr(x(i)))
不过必须注意,这种情况下,参数 sum0 必须为你那个(T上的)"加法"运算的"单位元",或者是被"加"的第一个元素。
举个典型的例子,计算 a(0) * a(1) * ... * a(n-1)
如果写成 For(0, n-1, 0, Function (product, i) product * a(i))
这样就错了!
应当写成 For(0, n-1, 1, Function (product, i) product * a(i))
或者 For(1, n-1, a(0), Function (product, i) product * a(i))
================================================================================
这里再贴一下VB6版的。但是注意:
- VB6没有泛型,我就用Variant凑合了
- VB6没有(内部的)回调函数,于是我们只好用多态代替。多态的实现方法有二:实现接口和在运行时按方法名调用。
而从性能考虑,我们显然只能采用前者(实现接口)。具体步骤是:在某个类中写上 Implements <类名> 以继承一个类的接口类(VB6中每一个类都自动具备一个(方法属性一样的)接口类),并实现其中的方法,做法是:Private Function <类名>_<方法名>。然后那个方法就是你的回调函数,而我们可以通过那个类的(任意一个)对象来调用你的回调函数。
Public Function For_(ByVal from_ As Long, ByVal to_ As Long, ByVal fAdd As For_fAdd, ByVal fElem As For_FElem) As Variant
If from_ > to_ Then
Err.Raise 0
Exit Function
End If
For_ = fElem.f(from_)
Dim i As Long
For i = from_ + 1 To to_
For_ = fAdd.f(For_, fElem.f(i))
Next i
End Function
Public Function For__(ByVal from_ As Long, ByVal to_ As Long, ByVal sum0 As Variant, ByVal f As For_F) As Object
If from_ > to_ Then
For__ = sum0
Exit Function
End If
For__ = sum0
Dim i As Long
For i = from_ To to_
For__ = f.f(For__, fElem.f(i))
Next i
End Function
' For_FAdd.cls
' 你要建立一个类,并写上 Implements For_FAdd 然后实现 f (做法是 Function For_FAdd_f),
' 而 f 就是你的回调函数,通过你的类的(任意一个)对象就可以调用它。
Public Function f(ByVal a As Variant, ByVal b As Variant) As Variant
End Function
' For_FElem.cls
Public Function f(ByVal i As Long) As
End Function
' For_F.cls
Public Function f(ByVal a As Variant, ByVal i As Long) As Variant
End Function
|
|