如何定义仅含非负整数的Vector?解决push!调用报错问题
问题解答
错误原因分析
你遇到的问题有两个核心原因:
Array{>:Unsigned, 1}是类型对象,而非实际初始化的Vector实例,push!函数只能作用于已创建的容器实例,不能直接操作类型。9属于Int64类型(有符号整数),而Unsigned是无符号整数的抽象类型,Int64并不属于Unsigned的子类型,因此即使创建Vector{Unsigned}实例,也无法直接推入Int64值。
正确的Vector定义方式
1. 存储任意非负整数的Vector
如果只是需要存储非负整数,无需限定为无符号类型,可以定义兼容所有整数子类型的Vector:
# 创建空的可容纳任意Integer子类型的Vector l = Vector{<:Integer}() push!(l, 9) # 正常执行,Int64是Integer的子类型
如果必须使用无符号整数,需要将值显式转换为无符号类型:
l = Vector{UInt}() push!(l, UInt(9)) # 显式转换为UInt类型后推入
针对concat_ints函数的优化方案
需要明确:Julia的类型系统无法直接通过类型限定约束值的范围(比如强制元素为0-9),类型仅能约束数据类型。要替代断言逻辑,有两种可行方案:
方案1:放宽输入类型+保留断言
保留断言确保值范围,同时允许函数接受多种整数类型的Vector:
function concat_ints(l::Vector{<:Integer})::Int64 """ concat_ints([3, 4, 5]) == 345 """ @assert all(n -> 0 ≤ n ≤ 9, l) "Only digits in range 0:9 are allowed inputs" s = 0 for (i, n) in enumerate(reverse(l)) s += n * 10^(i-1) end return s end
该方案兼容Int64、UInt等多种整数类型的输入,同时保证元素为合法数字。
方案2:自定义Digit类型替代断言
定义仅允许0-9的自定义类型,在创建元素时就完成合法性检查,函数内部无需断言:
struct Digit value::UInt8 function Digit(n::Integer) 0 ≤ n ≤ 9 || throw(ArgumentError("Digit must be between 0 and 9")) new(UInt8(n)) end end # 为Digit添加整数转换支持 Base.Int(d::Digit) = d.value Base.convert(::Type{Int}, d::Digit) = Int(d.value) function concat_ints(l::Vector{Digit})::Int64 """ concat_ints([Digit(3), Digit(4), Digit(5)]) == 345 """ s = 0 for (i, d) in enumerate(reverse(l)) s += Int(d) * 10^(i-1) end return s end
使用时需将数字包装为Digit实例,例如concat_ints([Digit(3), Digit(4), Digit(5)]),创建实例时会自动检查值是否在0-9范围内。
内容的提问来源于stack exchange,提问作者René
相关产品推荐
相关产品推荐

