You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Julia struct计算RMSE时遇UndefVarError: @property未定义问题

Julia RMSE Struct 报错问题解决

问题重现

尝试用Julia编写类似Python类的struct计算数组RMSE,代码如下:

struct RMSE
    _array1::Array
    _array2::Array
    
    function RMSE(array1::Array, array2::Array)
        new(array1, array2)
    end
    
    # getter function for array1
    function RMSE.array1(r::RMSE)
        return r._array1
    end
    
    # setter function for array1
    function RMSE.array1(r::RMSE, value::Array)
        r._array1 = value
    end
    
    # getter function for array2
    function RMSE.array2(r::RMSE)
        return r._array2
    end
    
    # setter function for array2
    function RMSE.array2(r::RMSE, value::Array)
        r._array2 = value
    end
    
    # @property macro to for array1 and array2 with both a getter and a setter
    @property array1()
    @property array2()
    
    # Calculating the RMSE between the array1 and array2
    function RMSE.calculate(r::RMSE)
        sum_squares = sum((r.array1 - r.array2).^2)
        rmse = sqrt(sum_squares / length(r.array1))
        return rmse
    end
end

r = RMSE([1, 2, 3], [1, 2, 3])

r.array1 = [4, 5, 6]
r.array2 = [7, 8, 9]

rmse = r.calculate
println(rmse)

运行后报错:

ERROR: LoadError: UndefVarError: @property not defined
in expression starting at /home/Julia/rmse_struct.jl:30
in expression starting at /home/Julia/rmse_struct.jl:1

使用Julia 1.7.2版本,误以为@property是Julia 0.7+内置功能,询问错误原因。


问题分析与解决

核心错误原因

Julia标准库中没有内置@property宏,该宏来自第三方包Properties.jl,直接使用会触发未定义错误。此外代码还有两个隐性问题:

  • 默认struct是不可变类型,无法修改字段值,setter函数会执行失败;
  • 调用calculate时未加括号,仅获取函数对象而非执行计算。

修正方案

方案1:原生Julia实现(无需第三方包)

用mutable struct定义可变类型,通过自定义方法实现属性访问:

mutable struct RMSE
    _array1::Array
    _array2::Array
    
    function RMSE(array1::Array, array2::Array)
        @assert length(array1) == length(array2) "两个数组长度必须相等"
        new(array1, array2)
    end
end

# array1的getter与setter
function array1(r::RMSE)
    return r._array1
end

function array1!(r::RMSE, value::Array)
    @assert length(value) == length(r._array2) "新数组长度需与原数组一致"
    r._array1 = value
end

# array2的getter与setter
function array2(r::RMSE)
    return r._array2
end

function array2!(r::RMSE, value::Array)
    @assert length(value) == length(r._array1) "新数组长度需与原数组一致"
    r._array2 = value
end

# RMSE计算方法
function calculate(r::RMSE)
    sum_squares = sum((array1(r) - array2(r)).^2)
    return sqrt(sum_squares / length(array1(r)))
end

# 测试代码
r = RMSE([1,2,3], [1,2,3])
array1!(r, [4,5,6])
array2!(r, [7,8,9])
rmse = calculate(r)
println(rmse)  # 输出:5.196152422706632

方案2:使用Properties.jl第三方包

若坚持用@property宏,需先安装包:

using Pkg
Pkg.add("Properties")

修改后的代码:

using Properties

mutable struct RMSE
    _array1::Array
    _array2::Array
    
    function RMSE(array1::Array, array2::Array)
        @assert length(array1) == length(array2) "两个数组长度必须相等"
        new(array1, array2)
    end
    
    # 定义array1的属性访问
    @property array1() = getfield(self, :_array1)
    @property array1!(value::Array) = begin
        @assert length(value) == length(self._array2) "新数组长度需一致"
        setfield!(self, :_array1, value)
    end
    
    # 定义array2的属性访问
    @property array2() = getfield(self, :_array2)
    @property array2!(value::Array) = begin
        @assert length(value) == length(self._array1) "新数组长度需一致"
        setfield!(self, :_array2, value)
    end
    
    # RMSE计算方法
    function calculate(r::RMSE)
        sum_squares = sum((r.array1 - r.array2).^2)
        return sqrt(sum_squares / length(r.array1))
    end
end

# 测试代码
r = RMSE([1,2,3], [1,2,3])
r.array1 = [4,5,6]
r.array2 = [7,8,9]
rmse = r.calculate()
println(rmse)

关键注意事项

  • 要修改struct字段必须使用mutable struct,默认struct不可变;
  • 调用方法时必须加括号(如r.calculate()),否则仅返回函数对象;
  • 添加数组长度校验可避免后续计算出错。

内容的提问来源于stack exchange,提问作者naughty_waves

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 19:45:31