在朱莉娅,我可以通过
定义一个接受Type
所有子类型的函数
function foo{T<:Type}(bar::T, arg::T) end
但这强加了bar
和arg
与Type
相同的子类型。是否有一种速记来定义一个函数,该函数接受Type
和bar
的{{1}}的不同子类型?我知道我可以做到
arg
但对于具有多个参数的函数,它变得非常麻烦。
答案 0 :(得分:3)
当foreach (ManagementObject _object in _class.GetInstances())
{
string groups = _object["GroupComponent"].ToString();
int i = groups.LastIndexOf('=') + 1;
string groupsName = groups.Substring(i);
richTextBox1.AppendText(groupsName + "\r\n\r\n");
}
左侧使用的类型是抽象类型时,声明为T<:Type
类型的函数参数将接受属于该类型的所有内容抽象,包括属于从属(继承)抽象的东西。
在大多数情况下,这些东西都是具体类型的实现,类型的实例化。具体类型可以具有抽象类型作为其超类型,并且该抽象类型可以具有另一个更抽象类型作为其超类型,等等。 T
是最超级的超类型,是抽象类型树的根。
在示例中
Any
在 function foo{T<:Type}(bar::T, arg::T) ... end
的每次调用中,foo
只接受T
或其中Type
的一种子类型。这就是Type
和bar
必须共享此版本的arg
要匹配和调用的相同特定类型的原因。它解释了为什么下一个例子匹配并被称为
foo
当 function foo{T<:Type, U<:Type}(bar::T, arg::U) ... end
和foo
是bar
的每个子类型但是是两种不同具体类型的实现时(例如Type
和Int32
共享抽象超类型{ {1}})。
使用您打算接受不同类型事物的参数没有一般简写;不同的排序共享一个共同的抽象类型是有用的信息,并允许您定义调用Int64
的第一种和第二种方式。这种管理算法规范的灵活方式通常可以简化实现。这是朱莉娅的多重调度提供的一些力量。
在某些情况下,使用Integer
可以简化函数签名的编写。 foo
适用于使用共享超类型的非重叠子类集合进行选择性调度。
typealias
```
答案 1 :(得分:2)
我只想把它写成
function foo(bar::MyType, arg::MyType)
...
end
在函数内部,如果需要具体类型,请使用typeof(bar)
和typeof(arg)
。这些是常量,因此不会影响性能。
当然,我假设您将Type
表示为某些用户定义的类型,而不是内置的Type
类型。
即使参数是数组,也不需要参数化地编写函数。这是完全可以的
function foo(bar::AbstractArray, arg::AbstractArray)
...
end
如果需要,并在函数内部使用eltype(bar)
和eltype(arg)
。但是,如果需要eltype
,我个人会使用参数形式。