我正在尝试通过阅读文档来学习Julia,他们的代码看起来像这样:
function testFunction(x::Number)
return x+5
end
这是一个适用于Juila中许多数字类型的函数。
但是,如果我尝试做类似的事情,就像这样:
function testFunction2(x::Array{Number})
return x
end
我收到以下错误:
ERROR: MethodError: no method matching testFunction2(::Array{Int64,1})
Closest candidates are:
testFunction2(::Array{Number,N} where N) at /Users/.../Desktop/Test.jl:45
我做错了吗?我想这个:Array{Float64}
是你如何声明一个特定类型的数组,但使用类似Number
的类型,适用于常规情况,在这里不起作用...任何见解都表示赞赏。
答案 0 :(得分:6)
定义
function testFunction2(x::Array{Number})
return x
end
是接受Array{Number}
作为输入的识别函数。所以以下内容将起作用:
testFunction2(collect((1,3,-2.7,5+2im)))
但这不工作:
testFunction2([1,3,7,9])
从这里可以看出:
julia> typeof(collect((1,3,-2.7,5+2im)))
Array{Number,1}
julia> typeof([1,3,7,9])
Array{Int64,1}
第一个匹配x
定义中testFunction2
的类型,第二个匹配Array{Number}
。 (请注意,Array{Number,1}
是Number
的同义词。)
您正在寻找的是一个函数,它接受任何元素类型的数组,该类型是function testFunction2(x::Array{T}) where {T<:Number}
return x
end
的子类型。这样做:
T
现在我们有一个参数Number
,允许它是function testFunction2(x::Array{<:Number})
return x
end
的任何子类型。你也可以使用糖
testFunction2(x::Array{<:Number}) = x
甚至是import UIKit
struct One {
let cellID: String
let name: String
let lastName: String
let cellID2: String
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var arrayOne = [One(cellID: "1", name: "hello", lastName: "hello last", cellID2: "1"), One(cellID: "1", name: "hello", lastName: "hello last", cellID2: "1"), One(cellID: "1", name: "hello", lastName: "hello last", cellID2: "2"), One(cellID: "1", name: "hello", lastName: "hello last", cellID2: "1"), One(cellID: "1", name: "hello", lastName: "hello last", cellID2: "2"), One(cellID: "1", name: "hello", lastName: "hello last", cellID2: "1")]
@IBOutlet weak var compareTableView: UITableView!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayOne.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CompareTableViewCell") as! CompareTableViewCell
let arrayID = arrayOne[indexPath.row]
if arrayID.cellID == arrayID.cellID2{
cell.lblOne.text = arrayID.cellID
cell.lblTwo.text = arrayID.cellID2
cell.lblThree.text = arrayID.lastName
cell.lblFour.text = arrayID.name
}
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}
}
。
答案 1 :(得分:4)
添加到另一个答案:手册中的示例与您的代码之间的行为存在差异的原因是,在您的情况下,Number
用作另一种类型中的类型参数({{1 }})。与Array
单独使用类型相比,它会进行更严格的类型检查。正如@StefanKarpinski在this answer中所说,
这是Julia中参数类型不变性的结果。有关详细信息,请参阅手册中的chapter on types。
(链接更正为当前。)
手册的关键点是:&#34;即使Float64&lt;:Real我们也没有Point {Float64}&lt;:Point {Real}。&#34;同样在您的情况下,即使我们有Number
,我们也不会拥有Int64 <: Number
,这就是类型匹配失败的原因。
一般来说,你可以编写Array{Int64} <: Array{Number}
来匹配任何数字类型,你可以编写x::Number
来匹配任何字符串类型{{{1}的子类型但是如果您将抽象类型作为类型参数用作另一种类型的一部分,那么您必须明确指定您希望它匹配参数类型的所有子类型,即{{1} }或p::AbstractString
。