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가 바깥 인스턴스에 의존해서 지금까지는 바깥 클래스의 서브클래스 안에 넣는…

    답글 1최근 활동 scala
  2. Lean4의 have 바인딩과 let 바인딩 비교

    아래 두 표현식을 보니 그리고 똑같이 동작하더군요. 정리를 증명할 때도 마찬가지예요. 서로 바꿔 써도 되나요? 차이가 뭔가요?

    답글 3최근 활동 lean-4
  3. 문자열 배열을 값으로 갖는 TypeScript Map 초기화

    각 항목이 문자열 배열을 담는 Map을 만들고 있어요. 타입 선언과 초기화를 한 문장으로 같이 하려면 어떻게 하나요? 제 (단순한) 시도는 이랬어요: 그랬더니 이렇게 나와요:

    답글 2최근 활동 typescript