初学Julia
练习的时候尝试重载+运算符,
查了一下文档,发现正确的写法是:
import Base
Base.:+(a, b) = Point(a.x + b.x, a.y + b.y)
请问该如何理解这里的Base.:+ ?
除了操作符函数之外,在什么场合下还会用到“.:”的这种写法?
初学Julia
练习的时候尝试重载+运算符,
查了一下文档,发现正确的写法是:
import Base
Base.:+(a, b) = Point(a.x + b.x, a.y + b.y)
请问该如何理解这里的Base.:+ ?
除了操作符函数之外,在什么场合下还会用到“.:”的这种写法?
不是 .:
,而是 :+
.如果你重载 println
的话,就是 Base.println
,重载 *
就是 Base.:*
因为 Base.+
会被解析成 Base .+
就是一个叫 Base
的变量.(我猜的) 另外可以看Juliacon 2021 讲 元编程(Meta Programming) 的那个视频,讲得挺好的
julia> +(x, y) = x*y
+ (generic function with 1 method) # 这里重新定义了一个新的函数,而不是在原有的 Base 里作运算符重载
julia> +(2, 3)
6
正如 @Sukanka 所说 Base.+
在语法解析上有歧义,所以这里需要用 :+
来表示它
:+
代表一个 Symbol
julia> :+
:+
julia> :+ |> typeof
Symbol
跳到元编程一章仔细读了一下,恍然大悟~
读元编程一章时发现还有这种写法:
julia> : ( : )
: ( : )
julia> : ( : : )
: ( : : )
有意思~
请问要是想重载==的话应该怎么写呢 ?Base.:==好像不大对
Base.:(==)
some_function_name
Length
是一个有歧义的名称 (Julia 里有 Base.length
)lhs
与 rhs
是同一类型Vec2
完全可以使用 StaticArrays里的 SVector{2, T}
来取代)struct Vec2{T<:Real}
x::T
y::T
end
Vec2(x::Real, y::Real) = Vec2(promote(x, y)...)
for op in (:+, :-, :*, :/)
@eval Base.$op(lhs::Vec2, rhs::Vec2) = Vec2($op(lhs.x, rhs.x), $op(lhs.y, rhs.y))
end
Base.zero(v::T) where T<:Vec2 = T(0, 0)
Base.show(io::IO, v::Vec2) = println(io, v.x, "\t", v.y)
radius(v::Vec2) = sqrt(v.x^2 + v.y^2)
dot(lhs::Vec2, rhs::Vec2) = lhs.x * rhs.x + lhs.y * rhs.y
function normalize(v::T) where T<:Vec2
r = radius(v)
return == 0 ? zero(T) : T(v.x/r, v.y/r)
end
感谢感谢~
我晚上学习一下^_^
研究了一下SVector然后继续修改程序
这样写是不是更像Julia的代码?
请问还有没有什么不够Julia的地方?
module Vec2
using LinearAlgebra
using StaticArrays
function Init(x::T, y::T) where {T}
SVector{2, T}(x, y)
end
X(v::SVector{2, T}) where {T} = v[1]
Y(v::SVector{2, T}) where {T} = v[2]
Dot(v1::SVector{2, T}, v2::SVector{2, T}) where {T} = dot(v1, v2)
Normalize(v::SVector{2, T}) where {T} = normalize(v)
Length(v::SVector{2, T}) where {T} = norm(v)
function Proj(v::SVector{2, T}, p::SVector{2, T}) where {T}
vp = normalize(p)
dot(v, vp)
end
end
T
类型的时候就可以不去写它。using LinearAlgebra
using StaticArrays
const Point{T} = SVector{2, T}
project(v::Point, p::Point) = dot(v, normalize(p))
有点找到感觉了~
感谢!!