转发类型声明

时间:2015-10-01 07:53:58

标签: types julia

我想知道是否有可能在julia中为变量分配自定义或现有类型而不调用它的构造函数。

类似于c ++中类的前向声明。

这是我打算实现的一个例子:

type foo
    a
end

#custom type
a = foo
b = foo

#julia type, force c to be of type Int
c = Int    


a.a = 5.5
b.a = 4.5

c = 6

修改澄清我的问题:

在C ++或Fortran中,通常的编码实践是在某个时刻声明变量以供以后使用。

我不记得正确的Fortran语法,但在C ++中你会写出类似的东西:

class foo;
class bar;
int a;

class foo{
private:
    bar myBar;

public:
    foo(int a){ myBar( a ); }  
}    

class bar{ 
public: 
    bar(int a){ 
        std::cout << a << std::endl;
    } 
}

a = 3;
foo( a );

此代码结构的优点是它允许您在使用它们之前定义对象/类型/变量。

3 个答案:

答案 0 :(得分:7)

您可以在全局范围中执行变量声明;这些是Julia中引入新scope

的结构
  

语言中的某些结构引入了作用域块,这些作用域是有资格成为某些变量集合范围的代码区域。变量的范围不能是任意一组源代码行;相反,它将始终与其中一个块对齐。引入这些块的构造是:

     
      
  • 函数体(语法)
  •   
  • while循环
  •   
  • for loops
  •   
  • 试试块
  •   
  • catch blocks
  •   
  • 终于阻止了
  •   
  • let blocks
  •   
  • 类型块。
  •   
     

值得注意的是,此列表中缺少的是开始块和if块,这些块不会引入新的范围块。

您可以选择使用type declarations

julia> x
ERROR: UndefVarError: x not defined

julia> x::Int
ERROR: UndefVarError: x not defined

julia> begin x end   # still in global scope
ERROR: UndefVarError: x not defined

julia> begin x::Int end
ERROR: UndefVarError: x not defined

julia> let x end    # local scope

julia> let x; x end
ERROR: UndefVarError: x not defined

请注意,Julia会尝试将值转换为指定的类型:

julia> let 
           x::Int # declare variables
           y::Float64 = 7    # converts (if possible)

           x = y    # converts (if possible)
           x, y
       end
(7, 7.0)

julia> function foo(x, y)
           x::Int
           y::Float64
           z    # Any

           # there must be assignment for conversion to happen
           x, y = x, y

           z = 5im
           x, y, z
       end
foo (generic function with 1 method)

julia> foo(3.0, 7)
(3,7.0,0 + 5im)

已编辑的示例:

定义类型/不可变。

julia> type Foo{T<:Number}
           x::T
       end

julia> type Bar
           x
       end

julia> immutable Baz
           a
           b
           c
       end

定义转换方法。

julia> import Base.convert

julia> convert{T<:Number}(::Type{Foo{T}}, x::Number) = Foo(T(x))
convert (generic function with 535 methods)

julia> convert(::Type{Bar}, x) = Bar(x)
convert (generic function with 536 methods)

julia> convert(::Type{Baz}, xs::NTuple{3}) = Baz(xs...)
convert (generic function with 537 methods)

所以你可以这样做:

julia> let
           # decalre variables:
           a::Foo{Int}
           b::Foo{Float64}
           c::Bar
           d::Baz
           e::Int

           # assign values:
           e = 42
           a = e
           b = e
           c = string(e)
           d = 'a', e, "test"

           [a, b, c, d]
       end
4-element Array{Any,1}:
 Foo{Int64}(42)
 Foo{Float64}(42.0)
 Bar("42")
 Baz('a',42,"test")

julia>

答案 1 :(得分:3)

在我看来,你想要做的是创建一个类型的实例而不指定内容,然后在以后填写它。这可以通过创建一个未初始化某些字段的构造函数来实现:

type Foo
    a
    # inner constructor that leaves all fields uninitialized
    Foo() = new()
end

a = Foo()
b = Foo()

a.a = 5.5
b.a = 4.5

通过在内部构造函数中向new提供的参数少于类型包含字段的参数,最后的参数将变为未初始化。在为未初始化的字段分配值之前读取它是错误的。

这是你追求的吗?

答案 2 :(得分:2)

没有必要在Julia中预先声明变量,因为类型只是由用法定义。

如果您想限制某些类型,那么您可以这样做:

type MyType
    a::Int
end

(请注意,类型名称按惯例有初始资本。)

b = MyType(1)
c = MyType(2)
d = MyType(3.5)  # error