发新话题
打印

5 D语言 声明 Declarations

5 D语言 声明 Declarations

知识若不分享 实在没有意义 http://www.d-programming-language-china.org 20070417

点击下面网址查看原文:
http://www.d-programming-language-china.org

by: uFramer D语言论坛 http://www.d-programming-language-china.org
from: http://www.digitalmars.com/d/declaration.html
version: 基于D 1.012 (Apr 12, 2007)

D语言声明

QUOTE:
声明:
    typedef Decl
    alias Decl
    Decl

Decl:
    存储类别 Decl
    基本类型 多个声明符 ;
    基本类型 声明符 函数体

多个声明符:
    声明符初始值
    声明符初始值 , 声明符初始值列表

声明符初始值:
    声明符
    声明符 = 初始值

声明符标志符列表:
    声明符标志符
    声明符标志符 , 声明符标志符列表

声明符标志符:
    标志符
    标志符 = 初始值

基本类型:
    bit
    byte
    ubyte
    short
    ushort
    int
    uint
    long
    ulong
    char
    wchar
    dchar
    float
    double
    real
    ifloat
    idouble
    ireal
    cfloat
    cdouble
    creal
    void
    .标志符列表
    标志符列表
    Typeof
    Typeof . 标志符列表


基本类型2:
    *
    [ ]
    [ 表达式 ]
    [ 类型 ]
    delegate ( 参数列表 )
    function ( 参数列表 )

声明符:
    基本类型2 声明符
    标志符
    ( 声明符 )
    标志符 多个声明符后缀
    ( 声明符 ) 多个声明符后缀

多个声明符后缀:
    声明符后缀
    声明符后缀 多个声明符后缀

声明符后缀:
    [ ]
    [ 表达式 ]
    [ 类型 ]
    ( 参数列表 )

标志符列表:
    标志符
    标志符 . 标志符列表
    模板实例
    模板实例 . 标志符列表

Typeof:
    typeof ( 表达式 )

存储类别:
    abstract
    auto
    const
    deprecated
    final
    override
    static
    synchronized

类型:
    基本类型
    基本类型 声明符2

声明符2:
    基本类型2 声明符2
    ( 声明符2 )
    ( 声明符2 ) 声明符后缀

参数列表:
    参数
    参数 , 参数列表
    ...

参数:
    声明符
    声明符 = 赋值表达式
    InOut 声明符
    InOut 声明符 = 赋值表达式



Declaration:
        typedef Decl
        alias Decl
        Decl

Decl:
        StorageClasses Decl
        BasicType Declarators ;
        BasicType Declarator FunctionBody
    AutoDeclaration

Declarators:
        DeclaratorInitializer
        DeclaratorInitializer , DeclaratorIdentifierList

DeclaratorInitializer:
        Declarator
        Declarator = Initializer

DeclaratorIdentifierList:
        DeclaratorIdentifier
        DeclaratorIdentifier , DeclaratorIdentifierList

DeclaratorIdentifier:
        Identifier
        Identifier = Initializer

BasicType:
        bool
        byte
        ubyte
        short
        ushort
        int
        uint
        long
        ulong
        char
        wchar
        dchar
        float
        double
        real
        ifloat
        idouble
        ireal
        cfloat
        cdouble
        creal
        void
        .IdentifierList
        IdentifierList
        Typeof
        Typeof . IdentifierList

BasicType2:
        *
        [ ]
        [ Expression ]
        [ Type ]
        delegate Parameters
        function Parameters

Declarator:
        BasicType2 Declarator
        Identifier
        () Declarator
        Identifier DeclaratorSuffixes
        () Declarator    DeclaratorSuffixes

DeclaratorSuffixes:
        DeclaratorSuffix
        DeclaratorSuffix DeclaratorSuffixes

DeclaratorSuffix:
        [ ]
        [ Expression ]
        [ Type ]
    Parameters

IdentifierList:
        Identifier
        Identifier . IdentifierList
        TemplateInstance
        TemplateInstance . IdentifierList

Typeof:
        typeof ( Expression )

StorageClasses:
    StorageClass
    StorageClass StorageClasses

StorageClass:
        abstract
        auto
        const
        deprecated
        extern
        final
        invariant
        override
        scope
        static
        synchronized

Type:
        BasicType
        BasicType Declarator2

Declarator2:
        BasicType2 Declarator2
        ( Declarator2 )
        ( Declarator2 ) DeclaratorSuffixes

Parameters:
    ( ParameterList )
    ( )

ParameterList:
        Parameter
        Parameter , ParameterList
        Parameter ...
        ...

Parameter:
        Declarator
        Declarator = AssignExpression
        InOut Declarator
        InOut Declarator = AssignExpression

InOut:
        in
        out
        ref
        lazy

Initializer:
        void
    NonVoidInitializer

NonVoidInitializer:
        AssignExpression
        ArrayInitializer
        StructInitializer

ArrayInitializer:
    [ ]
    [ ArrayMemberInitializations ]

ArrayMemberInitializations:
    ArrayMemberInitialization
    ArrayMemberInitialization ,
    ArrayMemberInitialization , ArrayMemberInitializations

ArrayMemberInitialization:
    NonVoidInitializer
    AssignExpression : NonVoidInitializer

StructInitializer:
    {    }
    { StructMemberInitializers }

StructMemberInitializers:
    StructMemberInitializer
    StructMemberInitializer ,
    StructMemberInitializer , StructMemberInitializers

StructMemberInitializer:
    NonVoidInitializer
    Identifier : NonVoidInitializer

声明语法

声明语法通常从右向左读:

int x;        // x 是 int
int* x;        // x 是指向 int 的指针
int** x;        // x 是指向(指向 int 的指针)的指针
int[] x;        // x 是 int 数组
int*[] x;        // x 是指向 int 的指针的数组
int[]* x;        // x 是指向 int 数组的指针

数组,从右向左读(列优先):
D语言论坛 http://www.d-programming-language-china.org 按:原来译作从左向右读。明显,这里应该是从右向左读。

int[3] x;        // x 是有3个元素的 int 数组
int[3][5] x;    // x 是有5个元素的数组,每个元素是有3个元素的 int 数组
int[3]*[5] x;    // x 是有5个元素的数组,每个元素是指向有3个元素的 int 的数组的指针

指向函数的指针用关键字 function 声明:

int function(char) x;    // x 是指向函数的指针,函数有一个 char 的参数,返回值类型是 int
int function(char)[] x;    // x 是指向函数的指针的数组,函数有一个 char 的参数,返回值类型是 int

也可以使用 C 风格的数组声明方式(行优先):

int x[3];        // x 是有3个元素的 int 数组
int x[3][5];    // x 是有3个元素的数组,每个元素是有5个元素的 int 数组
int (*x[5])[3];    // x 是有5个元素的数组,每个元素是指向有3个元素的 int 的数组的指针
int (*x)(char);    // x 是指向函数的指针,函数有一个 char 的参数,返回值类型是 int
int (*[] x)(char);    // x 是指向函数的指针的数组,函数有一个 char 的参数,返回值类型是 int

在多重声明中,所有被声明的符号拥有相同的类型:

int x,y;        // x 和 y 是 int
int* x,y;        // x 和 y 是指向 int 的指针
int x,*y;        // 错误,多重类型
int[] x,y;    // x 和 y 是 int 数组
int x[],y;    // 错误,多重类型

隐式类型推断

QUOTE:
AutoDeclaration:
    StorageClasses Identifier = AssignExpression ;

If a declaration starts with a StorageClass and has a NonVoidInitializer from which the type can be inferred, the type on the declaration can be omitted.( 本文出处: http://www.d-programming-language-china.org )

static x = 3;        // x is type int
auto y = 4u;        // y is type uint
auto s = "string"; // s is type char[6]

class C { ... }

auto c = new C();    // c is a handle to an instance of class C

The NonVoidInitializer cannot contain forward references (this restriction may be removed in the future). The implicitly inferred type is statically bound to the declaration at compile time, not run time.

类型定义

可以通过 typedef 引入强类型。对于函数重载和调试器来说,在语义上,强类型是类型检查系统可以将其同其他类型区分的类型。

typedef int myint;

void foo(int x) { . }
void foo(myint m) { . }

.
myint b;
foo(b);        // 调用 foo(myint)

Typedef 可以指定一个不同于其底层类型(underlying type)的初始值:

typedef int myint = 7;
myint m;        // 初始化为 7

类型别名

有时为类型起一个别名是很方便的,例如可以作为一个冗长复杂类型(比如一个函数指针)的简写形式。在 D 中,可以使用别名声明达到这个目的:

alias abc.Foo.bar myint;

别名类型在语义上等价于原类型。调试器无法区分它们,在函数重载是也不会区分它们。例如:( 本文出处: http://www.d-programming-language-china.org )

alias int myint;

void foo(int x) { . }
void foo(myint m) { . }    //错误,多次定义了函数 foo

类型别名等价于 C 中的 typedef 。

别名声明

符号可以被声明为另一个符号的 别名 。例如:

import string;

alias string.strlen mylen;
...
int len = mylen("hello");    // 实际上调用的是 string.strlen()

下面的别名声明是合法的:( 本文出处: http://www.d-programming-language-china.org )

template Foo2(T) { alias T t; }
alias Foo2!(int) t1;
alias Foo2!(int).t t2;
alias t1.t t3;
alias t2 t4;

t1.t v1;        // v1 的类型是 int
t2 v2;        // v2 的类型是 int
t3 v3;        // v3 的类型是 int
t4 v4;        // v4 的类型是 int

别名符号可以将一个较长的符号简记为一个较短的符号,还可以将一个引用从一个符号重定位到另一个符号:

version (Win32)
{
    alias win32.foo myfoo;
}
version (linux)
{
    alias linux.bar myfoo;
}

别名可以用来从模块中‘导入’一个符号到当前作用域:( 本文出处: http://www.d-programming-language-china.org )

alias string.strlen strlen;

别名还可以‘导入’一系列的重载函数,这样就可以在当前作用域中重载函数:

class A {
    int foo(int a) { return 1; }
}

class B : A {
    int foo( int a, uint b ) { return 2; }
}

class C : B {
    int foo( int a ) { return 3; }
    alias B.foo foo;
}

class D : C    {
}


void test()
{
    D b = new D();
    int i;

    i = b.foo(1, 2u);    // 调用 B.foo
    i = b.foo(1);        // 调用 C.foo
}

注意:类型别名有时会同别名声明十分相似:

alias foo.bar abc;    // 类型还是符号?

在语义分析是将会区分这两种情况。

别名不能用于表达式:

struct S { static int i; }
S s;

alias s.i a;    // illegal, s.i is an expression
alias S.i b;    // ok
b = 4;        // sets S.i to 4

Extern Declarations

Variable declarations with the storage class extern are not allocated storage within the module. They must be defined in some other object file with a matching name which is then linked in. The primary usefulness of this is to connect with global variable declarations in C files.( 本文出处: http://www.d-programming-language-china.org )

typeof

Typeof 用来获得一个表达式的类型。例如:

void func(int i)
{
    typeof(i) j;        // j 是 int 型
    typeof(3 + 6.0) x;    // x 是 double 型
    typeof(1)* p;        // p 是指向 int 型的指针
    int[typeof[p]] a;    // a 的类型是 int[int*]

    printf("%d\n", typeof('c').size);    // 打印 1
    double c = cast(typeof(1.0))j;        // 将 j 转换为 double 型
}

表达式 不会被计算,只会生成它的类型:

void func()
{    int i = 1;
    typeof(++i) j;    // j 被声明为 int ,i 不会自增
    printf("%d\n", i);    // 打印出 1
}

有两种特殊情况:就算不在成员函数中,typeof(this) 也将生成 this 在非静态成员函数中的类型。类似的,typeof(super) 也将生成 super 在非静态成员函数中的类型。

class A { }

class B : A
{
    typeof(this) x;    // x 被声明为 B 型
    typeof(super) y;    // y 被声明为 A 型
}

struct C
{
    typeof(this) z;    // z 被声明为 C* 型
    typeof(super) q;    // 错误,C 没有父结构
}

typeof(this) r;        // 错误,没有包含在类或者结构中

在编写模板代码时 Typeof 大有用武之地。

Void Initializations

变量通常是显式初始化或设置为某类型的默认值。如果用void,变量并没有被子初始化,在设置值前使用它将为引发未定义程序行为。( 本文出处: http://www.d-programming-language-china.org )

void foo()
{
    int x = void;
    writefln(x);    // will print garbage
}

Therefore, one should only use void initializers as a last resort when optimizing critical code.

( lastupdate:20070421 最新文章请访问http://www.d-programming-language-china.org )

关于一大步成功社区:
yidabu提倡在交流中学习,在分享中提高
收集感兴趣的知识,写下心得,通过网络与别人一起分享
理解一点就实践一步,收获什么就分享什么,成功就是这样一点点一步步累积起来的
网络只是一个工具,只有自己身心提高才是实实在在的。d-programming-language-china.org为大家提供一个学习交流各种知识的平台

TOP

发新话题