julia - 为什么这个参数构造函数只适用于多行定义?
问题描述
我有一个Device
构造函数,只有在我使用多行函数语法定义它时才有效,但如果我使用单行函数语法定义它,它会失败,并出现以下错误:
ERROR: LoadError: UndefVarError: F not defined
(如果我删除F
)或ERROR: LoadError: UndefVarError: C not defined
但是,如果我只从方法签名(而不是部分)中删除F
和类型参数,它也可以工作。C
where {C<:UxnCpu, F<:Function}
69 abstract type AbstractCPU end
70 mutable struct Device{C<:AbstractCPU, F<:Function}
71 cpu::C
72 id_addr::Int
73 vector::UInt16
74 talk::F
75 mem::OVector{UInt8}
76 dat::OVector{UInt8}
77 end
78
79 function Device(cpu::C, id_addr::Int, talkfn::F)::Device where {C<:AbstractCPU, F<:Function}
80 d = Device(cpu, id_addr, 0x000, talkfn, cpu.ram.dat, OVector{UInt8}(0x10))
81 cpu.dev[id_addr] = d
82
83 return d
84 end
85
---> 86 Device(talkfn::F, cpu::C, id_addr::Int)::Device where {C<:AbstractCPU, F<:Function} = Device(cpu, id_addr, talkfn)
87
88 Device(cpu, id_addr::Int) where {C<:AbstractCPU} = begin
89 Device(cpu, id_addr) do d::Device, b0::UInt8, w::UInt8
90 return true
91 end
92 end
完整的堆栈跟踪是:
ERROR: LoadError: UndefVarError: F not defined
Stacktrace:
[1] top-level scope
@ C:\Users\ismae\Bin\uxn-dev\src\VarvaraEmulator.jl:86 <---
[2] include(fname::String)
@ Base.MainInclude .\client.jl:444
[3] top-level scope
@ REPL[6]:1
in expression starting at C:\Users\ismae\Bin\uxn-dev\src\VarvaraEmulator.jl:25
但是,这种解决方法确实有效:
Device(talkfn, cpu, id_addr::Int)::Device where {C<:AbstractCPU, F<:Function} = Device(cpu, id_addr, talkfn)
我原以为它会抱怨签名中的类型参数很少。
以下语法也不起作用:
Device(talkfn::F, cpu::C, id_addr::Int)::Device where {C<:AbstractCPU, F<:Function} = begin
Device(cpu, id_addr, talkfn)
end
但是,这确实如此,这就是我最后留下的:
function Device(talkfn::F, cpu::C, id_addr::Int)::Device where {C<:AbstractCPU, F<:Function}
Device(cpu, id_addr, talkfn)
end
我想了解该错误来自哪里,我做错了什么?
我试图在一个最小的例子中复制它,但我做不到,这是我的完整代码供参考:
这是我目前的设置:
julia> versioninfo()
Julia Version 1.6.3
Commit ae8452a9e0 (2021-09-23 17:34 UTC)
Platform Info:
OS: Windows (x86_64-w64-mingw32)
CPU: Intel(R) Core(TM) i7-4710HQ CPU @ 2.50GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-11.0.1 (ORCJIT, haswell)
Environment:
JULIA_LOAD_PATH = C:\Users\\smae\Bin\uxn-dev\src;
(@v1.6) pkg> status
Status `C:\Users\ismae\.julia\environments\v1.6\Project.toml`
[6e4b80f9] BenchmarkTools v1.2.0
[c43c736e] Genie v3.2.0
[7eb4fadd] Match v1.1.0
[6fe1bfb0] OffsetArrays v1.10.7
[c3e4b0f8] Pluto v0.16.1
[b873ce64] ReplMaker v0.2.5
[98e33af6] SimpleDirectMediaLayer v0.3.0
[90137ffa] StaticArrays v1.2.13
最好的祝福。
解决方案
我认为这只是在有返回类型注释时解析参数的问题,而不是你的错。我可以用一个更简单的例子来复制错误。
这些工作:
function f1(x::F, y::C) where {F<:Integer, C<:Complex}
1
end
function f2(x::F, y::C)::Int where {F<:Integer, C<:Complex}
2
end
g1(x::F, y::C) where {F<:Integer, C<:Complex} = 3
但这不会:
g2(x::F, y::C)::Int where {F<:Integer, C<:Complex} = 4
编辑:从评论中,最后一种情况可以通过添加括号来修复:
(g2(x::F, y::C)::Int) where {F<:Integer, C<:Complex} = 4
推荐阅读
- amazon-web-services - QuickSight 数据分析问题
- unity3d - 自定义编辑器中的场景链接
- qt - 如何添加曲线路径以连接qt中两列的流小部件?
- python - How to get the names of the files using glob function in python?
- javascript - 阻止尝试创建 WebMediaPlayer,因为已经存在太多 WebMediaPlayer。- 加载视频标签时
- javascript - 找不到模块:'utils/ClassNames.js'。确保已安装此软件包
- javascript - 无法在 Flask 本地主机应用程序中使用 getCurrentPosition()
- facebook-javascript-sdk - 使用 JS SDK 登录 Facebook 即时游戏
- javascript - Vite glob 导入 - 访问 SvelteKit 中的正文/有效负载?
- javascript - 返回时变量值不会更新