首页 > 解决方案 > 为什么这个参数构造函数只适用于多行定义?

问题描述

我有一个Device构造函数,只有在我使用多行函数语法定义它时才有效,但如果我使用单行函数语法定义它,它会失败,并出现以下错误:

但是,如果我从方法签名(而不是部分)中删除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

最好的祝福。

标签: julia

解决方案


我认为这只是在有返回类型注释时解析参数的问题,而不是你的错。我可以用一个更简单的例子来复制错误。

这些工作:

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

推荐阅读