gpt4 book ai didi

julia - 参数类型构造函数中 "where"关键字的用途

转载 作者:行者123 更新时间:2023-12-03 15:54:34 25 4
gpt4 key购买 nike

对于 Julia 手册 parametric composite type example

struct Point{T}
x::T
y::T
end
可以编写一个外部构造函数,例如
Point(x::T, y::T) where {T} = Point{T}(x, y)
为什么是 where {T}需要的部分,即为什么不是
Point(x::T, y::T) = Point{T}(x, y)
可能的? Julia 提示 T没有定义,但它不能弄清楚 T是来自 :: 的类型句法?我是 Julia 的新手,所以我可能会遗漏一些非常基本的东西。

最佳答案

T是一个必须定义的变量。如果您没有在where 中定义它Julia 开始在外部范围内寻找它。这是一个例子:

julia> struct Point{T}
x::T
y::T
end

julia> Point(x::T, y::T) = Point{T}(x, y)
ERROR: UndefVarError: T not defined
Stacktrace:
[1] top-level scope at REPL[2]:1

julia> T = Integer
Integer

julia> Point(x::T, y::T) = Point{T}(x, y)
Point

julia> Point(1,1)
Point{Integer}(1, 1)
请注意,在此示例中,您没有得到预期的结果,正如您所希望的 Point{Int64}(1,1) .
现在最棘手的部分来了:
julia> Point(1.5,1.5)
Point{Float64}(1.5, 1.5)
你可能会问这是怎么回事。好:
julia> methods(Point)
# 2 methods for type constructor:
[1] (::Type{Point})(x::Integer, y::Integer) in Main at REPL[4]:1
[2] (::Type{Point})(x::T, y::T) where T in Main at REPL[1]:2
关键是 (::Type{Point})(x::T, y::T) where T struct 时已经默认定义了正如第二个定义所定义的那样,您刚刚为 T = Integer 添加了一个新方法.
简而言之 - 始终使用 where以避免得到令人惊讶的结果。例如,如果你写:
julia> T = String
String

julia> Point(1,1)
ERROR: MethodError: Cannot `convert` an object of type Int64 to an object of type String
你有问题。作为 Point的签名在定义时是固定的,但在正文中 T取自全局范围,而您已将其更改为 IntegerString ,所以你得到一个错误。

扩展@Oscar Smith 注意到 where 的位置对范围也很敏感,并告诉 Julia 在什么级别引入了“通配符”。例如:
ulia> T1 = Vector{Vector{T} where T<:Real}
Array{Array{T,1} where T<:Real,1}

julia> T2 = Vector{Vector{T}} where T<:Real
Array{Array{T,1},1} where T<:Real

julia> isconcretetype(T1)
true

julia> isconcretetype(T2)
false

julia> T1 isa UnionAll
false

julia> T2 isa UnionAll
true

julia> x = T1()
0-element Array{Array{T,1} where T<:Real,1}

julia> push!(x, [1,2])
1-element Array{Array{T,1} where T<:Real,1}:
[1, 2]

julia> push!(x, [1.0, 2.0])
2-element Array{Array{T,1} where T<:Real,1}:
[1, 2]
[1.0, 2.0]
你可以看到 T1是一种可以有实例的具体类型,我们创建了一个叫它 x 的类型.这个具体类型可以保存元素类型为 <:Real 的向量。 ,但它们的元素类型不必相同。
另一方面 T2UnionAll ,即它的一些“widlcards”是免费的(还不知道)。但是,限制是在所有匹配 T2 的具体类型中。所有向量必须具有相同的元素类型,因此:
julia> Vector{Vector{Int}} <: T2
true

julia> Vector{Vector{Real}} <: T2
true
julia> T1 <: T2
false
换句话说,在 T2通配符必须有一个具体值可以与具体类型匹配。

关于julia - 参数类型构造函数中 "where"关键字的用途,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62516021/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com