gpt4 book ai didi

Julia:具有内部构造函数的参数类型:new 和 typeof

转载 作者:行者123 更新时间:2023-12-03 18:47:45 26 4
gpt4 key购买 nike

试图理解参数类型和 new函数可用于内部方法。该手册指出“创建该类型的新对象的内部构造函数可用的特殊函数”。请参阅 上的手册部分新品 here以及 上的手册部分内部构造函数方法 here .
考虑一个旨在计算 x 和的内部方法,其中 x可以是向量或元组,并被赋予参数类型 T .自然需要的是 x 的元素类型。由他们的总和继承s .我好像不需要new为此,对吗?

struct M{T}
x::T
s
function M(x)
s = sum(x)
x,s
end
end


julia> M([1,2,3])
([1, 2, 3], 6)

julia> M([1.,2.,3.])
([1.0, 2.0, 3.0], 6.0)

julia> typeof(M([1.,2.,3.]))
Tuple{Vector{Float64}, Float64}
编辑: 更正! 我打算让内部构造函数的最后一行是 M(x,s) ......仍然是一个有趣的问题,所以我不会纠正它。怎么样 M(x,s)不同于 new{typeof(x)}(x,s) ? new的一种用法我看到的是结合 typeof() , 就像是:
struct M{T}
x::T
s
function M(x)
s = sum(x)
new{typeof(x)}(x,s)
end
end

julia> M([1,2,3])
M{Vector{Int64}}([1, 2, 3], 6)

julia> M([1.,2.,3.])
M{Vector{Float64}}([1.0, 2.0, 3.0], 6.0)
如果想约束怎么办 s到与 x 相同的类型?也就是说,例如,如果 x是向量,则 s应该是一个向量(在这种情况下,一个元素的向量)。我该怎么做?如果我用 x, new{typeof(x)}(s) 替换内部构造函数的最后一行,我得到了可以理解的错误:
MethodError: Cannot `convert` an object of type Int64 to an object of type Vector{Int64}

最佳答案

以下是规则:

  • 如果您正在为类型编写外部构造函数 M ,构造函数应该返回一个 M 的实例通过最终调用内部构造函数,如下所示:M(<args>) .
  • 如果您正在编写内部构造函数,这将覆盖默认的内部构造函数。所以你必须返回一个 M 的实例调用 new(<args>) .
  • new “特殊函数”的存在是为了允许构造一个还没有构造函数的类型。观察以下示例:
    julia> struct A
    x::Int
    function A(x)
    A(x)
    end
    end

    julia> A(4)
    ERROR: StackOverflowError:
    Stacktrace:
    [1] A(::Int64) at ./REPL[3]:4 (repeats 79984 times)
    这是 A 的构造函数的循环定义,这会导致堆栈溢出。你不能靠自己的引导来振作起来,所以 Julia 提供了 new作为规避这个问题的一种方式。
    您应该提供 new函数的参数数量等于结构中的字段数量。请注意 new函数将尝试转换其输入的类型以匹配结构体字段的声明类型:
    julia> struct B
    x::Float64
    B(x) = new(x)
    end

    julia> B(5)
    B(5.0)

    julia> B('a')
    B(97.0)

    julia> B("a")
    ERROR: MethodError: Cannot `convert` an object of type String to an object
    of type Float64
    (上面 B 的内部构造函数与默认的内部构造函数完全相同。)
    当您定义参数类型时, new function 必须提供与您的类型的参数数量相等的参数数量(并以相同的顺序),类似于参数类型的默认内部构造函数。首先观察参数类型的默认内部构造函数是如何使用的:
    julia> struct Foo{T}
    x::T
    end

    julia> Foo{String}("a")
    Foo{String}("a")
    现在,如果您正在为 Foo 编写内部构造函数, 而不是写 Foo{T}(x)在构造函数中,您将替换 Foonew ,像这样: new{T}(x) .
    您可能需要 typeof帮助定义构造函数,但通常你不这样做。这是您定义 M 的一种方式类型:
    struct M{I, T}
    x::I
    s::T

    function M(x::I) where I
    s = sum(x)
    new{I, typeof(s)}(x, s)
    end
    end
    我正在使用 typeof在这里,以便 I可以是任何返回数字的可迭代类型:
    julia> typeof(M(1:3))
    M{UnitRange{Int64},Int64}

    julia> g = (rand() for _ in 1:10)
    Base.Generator{UnitRange{Int64},var"#5#6"}(var"#5#6"(), 1:10)

    julia> typeof(M(g))
    M{Base.Generator{UnitRange{Int64},var"#5#6"},Float64}
    请注意,在使用 new 时需要为您的类型提供参数。在参数类型的内部构造函数中:
    julia> struct C{T}
    x::Int
    C(x) = new(x)
    end
    ERROR: syntax: too few type parameters specified in "new{...}" around REPL[6]:1

    关于Julia:具有内部构造函数的参数类型:new 和 typeof,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67578998/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com