如何在不限制其维度的情况下为函数参数指定类型?

Posted

技术标签:

【中文标题】如何在不限制其维度的情况下为函数参数指定类型?【英文标题】:How can I specify a type for a function argument without restricting its dimensions? 【发布时间】:2015-03-20 03:05:24 【问题描述】:

在 Julia 中,我想将函数参数的类型指定为数组数组。所以我有

function fooT <: Any(x::ArrayArrayT)

但如果我在 REPL 中设置参数x,例如:

x = Array[[0,1],[1,2,3],[0,1,2,4]]

然后它会自动获得以下类型分配(例如),其中包括其维度:

x::ArrayArrayT,N,1

这样我就会得到错误

ERROR: `foo` has no method matching foo(::ArrayArrayT,N,1).

我根本不想限制数组维度,所以我认为解决方案可能类似于

function fooT <: Any, N <: Number(x::ArrayArrayT,N,N)

但这也不起作用。

如何将参数类型指定为数组数组?

【问题讨论】:

您能否举例说明如何生成类似于您的x 的内容?我的预感是你遇到了invariance,像fooT&lt;:Array(x::ArrayT) 这样的定义就可以解决问题。 是的,这行得通,我不确定将T&lt;:Array 位放入的规则。例如,如果我有多个具有相同问题的参数,我该如何输入多种类型参数?感谢您的链接,它非常有帮助,我不知道在哪里看。我在问题中添加了一个如何生成x 的示例。 【参考方案1】:

给定一个数组数组x = Array[isodd(i) ? [1i,2i] : [1.0i 2.0i] for i=1:10],Julia 将其类型报告为ArrayArrayT,N,1。这是欺骗性的,因为它似乎暗示存在一些T 和一些N 与上述类型匹配。但事实并非如此:奇数元素的类型为ArrayInt,1,偶数元素的类型为ArrayFloat64,2。因此,当您尝试使用类型参数为foo 编写方法时:

fooT,N(::ArrayArrayT,N,1) = T,N

xTN 是什么?显然,不存在这样的 N —— 它是 both 1 和 2!而且这些子数组的元素不是Any 类型——它们都是IntFloat64。这同样适用于 Array[[0,1],[0,1,2]],即使在您的示例中您知道 TN 是一致的,但 Julia 的类型系统却不是……而且您可能会推送不是 Int 向量的元素。

有很多方法可以解决这个问题。最好的方法是尝试确保您的数组始终具有具体的(或至少统一的)元素类型,但这并不总是可能的。鉴于上面的示例x,您可以改为写:x = ArrayInt,1[[0,1],[1,2,3],[0,1,2,4]]

另一种选择是更改您的函数签名:

fooN(x::ArrayArray,N) = 1 # Will *only* work for arrays like x above
fooT<:Array, N(x::ArrayT,N = 2 # Will work for all arrays of arrays

由于invariance,第一个仅适用于您具有该类型的确切类型,而第二个适用于所有数组数组,包括类型不佳的和具体的。

(编辑:最后一点,N&lt;:Number 不会匹配文字数字。它将匹配作为Number 子类型的类型,例如RealInt。目前无法表示类型参数必须是类型为Int,超出了N 是整数的约定。

【讨论】:

以上是关于如何在不限制其维度的情况下为函数参数指定类型?的主要内容,如果未能解决你的问题,请参考以下文章

尝试在不指定返回参数的情况下调用存储的函数“dbname”。“functionname”

有没有一种方法可以在不使用大量分支语句的情况下为无符号整数编写 qsort 比较函数?

如何在不改变文本透明度的情况下为 UILabel 设置背景图像并调整其 alpha?

如何在不为其创建专用网站的情况下为我的应用提供隐私政策?

如何在不将其备份到 iCloud 的情况下为我的应用程序提供演示数据?

装饰器的理解