Julia 中的变量在构造时会改变其类型

Boj*_*eno 3 constructor julia

我是 Julia 编程的新手,面临着一种令人困惑的情况,我根本无法理解。所以,这就是我想做的:我有两个结构:ShoePerson,其中Person包含Shoe

代码如下所示:

struct Shoe
  size  :: Int64
  brand :: String
end

struct Person
  age  :: Int64
  shoe :: Shoe

  function Person(a::Int64, s::Shoe)
    age  = a
    shoe = s
  end

  function Person()
    age  = 33
    shoe = Shoe(17,"Nike")
  end
end

ian = Person(17, Shoe(32,"Puma"))
tom = Person()

println(typeof(ian))
println(typeof(tom))
Run Code Online (Sandbox Code Playgroud)

令我大吃一惊的iantom,我试图将其定义为人,结果却是鞋子。知道我做错了什么吗?

For*_*Bru 9

function Person,作为 struct 的构造函数Person,应该返回 的一个实例struct Person,但因为它的最后一行是shoe = Shoe(17,"Nike")(并且因为赋值是一个计算结果的表达式shoe),所以它最终返回该Shoe

构造函数应该调用内置new构造函数:

struct Person
  age  :: Int64
  shoe :: Shoe

  # This function is redundant since
  # it does exactly the same thing as the `new` constructor
  function Person(a::Int64, s::Shoe)
    age  = a
    shoe = s

    new(age, shoe)
  end

  function Person()
    age  = 33
    shoe = Shoe(17,"Nike")

    new(age, shoe)
  end
end
Run Code Online (Sandbox Code Playgroud)

AFAIK,您不需要使用构造函数,除非它们正在进行输入验证。例如,您确实需要一个构造函数来确保不可能Person用 negative构造 a ,因为可以为负数。(您也可以通过使用 来确保这一点。但是这样您就必须始终以十六进制 ( ) 编写,这有点烦人)ageInt64age >= 0UInt64170x11

我会这样写:

struct Person
  age  :: Int64
  shoe :: Shoe

  function Person(age::Int64, shoe::Shoe)
    @assert age >= 0

    new(age, shoe)
  end
end

# Put other constructors outside
Person() = Person(33, Shoe(17, "Nike"))
Run Code Online (Sandbox Code Playgroud)

例子:

julia> Person(-1, Shoe(0, "Hello"))
ERROR: AssertionError: age >= 0
Stacktrace:
 [1] Person(age::Int64, shoe::Shoe)
   @ Main ./REPL[3]:6
 [2] top-level scope
   @ REPL[5]:1

julia> Person()
Person(33, Shoe(17, "Nike"))
Run Code Online (Sandbox Code Playgroud)