openlang

为什么我的结构体变成了 Float64?

我遇到了一个无法解释的现象。我的代码用结构体传递几个参数。有些函数能正常接收,另一个却不行。也许其他人能看出我漏掉的错误。

这个 MWE 看起来都正常,直到最后一行报错。

using FlexUnits: QuantFieldVector, DimsMod

using Revise

gravity = 9.81u"m/s^2"

net_load(diameter, config) = @. 2*config.initial_load*(sin(acos((config.drum+config.gap)/(config.drum+diameter)))) - π/4*(diameter^2 - config.core^2)*config.density*gravity

limited_load(diameter, config) = max.(net_load(diameter, config), config.min_load)

line_load(diameter, config) = @. (π/4*(diameter^2 - config.core^2)*config.density*gravity + limited_load(diameter, config))/(2*sin(acos((config.drum+config.gap)/(config.drum+diameter))))

mutable struct Carrier{T} <: QuantFieldVector{7,T}
    drum::Quantity{T, D"m"}
    gap::Quantity{T, D"m"}
    core::Quantity{T, D"m"}
    span::Quantity{T, D"m"}
    min_load::Quantity{T, D"N/m"}
    initial_load::Quantity{T, D"N/m"}
    density::Quantity{T, D"kg/m^3"}
end

config = Carrier(26u"in", 31u"mm", 110u"mm", 1.4u"m", 5u"lbf/in",14u"lbf/in", 860u"kg/m^3")
transition_diameter = 0.9u"m"

config.initial_load
net_load(440u"mm", config)
limited_load(440u"mm", config)
line_load(440u"mm", config)
ERROR: FieldError: type Float64 has no field `initial_load`; Float64 has no fields at all.
Stacktrace:
  [1] getproperty
    @ .\Base_compiler.jl:57 [inlined]
  [2] net_load(diameter::Quantity{Float64, StaticDims{m}}, config::Float64)
    @ Main .\REPL[83]:2
  [3] limited_load(diameter::Quantity{Float64, StaticDims{m}}, config::Float64)
    @ Main .\REPL[82]:2
从英语翻译查看原文

后续讨论 2

顺着彼此的依据读下去
  1. 固定链接

    最后一行调用了 limited_load.(diameter, config)。因为 config 可以迭代,这里的广播行为大致相当于 [limited_load(diameter, item) for item in config]。每个 item 里面似乎是某个字段的 value*,它的类型为 Float64(T)。随后你的 net_load 在这个 Float64 上访问 item.initial_load。

    *补充,这份参考文档(https://deduction42.github.io/FlexUnits.jl/stable/types/#QuantFieldArrray)确认,与 getproperty 不同,getindex 返回的是数值标量,而不是 Quantity。

    一般来说,我不喜欢 @. 宏,因为它让你想广播哪些操作变得不清楚,从而导致这类错误。(其实也完全不需要 π ./ 4 这样的操作。)

    说实话,我不明白这里的 line_load、limited_load 或 net_load 为什么需要广播。比如最后一个函数,定义右侧的变量看起来不都是标量吗?我不熟悉这些方程的含义,不过

    julia> line_load(diameter, config) = (π/4*(diameter^2 - config.core^2)*config.density*gravity + limited_load(diameter, config))/(2*sin(acos((config.drum+config.gap)/(config.drum+diameter))))
    line_load (generic function with 1 method)
    
    julia> line_load(440u"mm", config)
    2451.775693450669 kg/s²

    可以正常运行(即使在 limited_load 和 net_load 中保留可能没有必要的广播也一样)。

    从英语翻译查看原文

同一个问题的其他角度

  1. 怎样继承另一个类里面的类?

    你好, 在一个我无法修改代码的包里,类的层次结构如下。 我想给 Inner 加个方便使用的包装,但因为 Inner 依赖外层实例,目前只做到把它放进外层类的子类里面。 可惜,在多个地方继承 Outer,就意味着每个新子类里都得重复这个方便使用的 ca…

    回复 1最近活动 scala
  2. 比较 Lean4 中的 have 和 let 绑定

    我发现下面两个表达式 以及 行为完全相同。证明定理时也是这样。 它们可以互换吗?区别在哪里?

    回复 3最近活动 lean-4
  3. 初始化以字符串数组为值的 TypeScript Map

    我在创建一个 Map,其中每个条目都保存字符串数组。怎样在一条语句中同时声明类型并完成初始化? 我(天真地)这样试了一下。 结果是下面这个错误。

    回复 2最近活动 typescript