1
2
3
4
maturin build -r -i
cargo build -release
rc icon.rc
cargo rustc --release -- -C link-arg=./src/icon.res

Allowable Types for Constants
常量允许的类型

Slice allows you to define constants for the following types:

An integral type (bool, byte, short, int, long)
A floating point type (float or double)
string
enum

Slice 允许定义以下类型的常量:
整型(bool、byte、short、int、long)
浮点类型(float 或 double)
字符串
枚举

Here are a few examples:

1
2
3
4
5
6
7
8
9
10
11
module M
{
const bool AppendByDefault = true;
const byte LowerNibble = 0x0f;
const string Advice = "Don't Panic!";
const short TheAnswer = 42;
const double PI = 3.1416;

enum Fruit { Apple, Pear, Orange }
const Fruit FavoriteFruit = Pear;
}

The syntax for literals is the same as for C++ and Java (with a few minor exceptions).
文字的语法与 C++ 和 Java 相同(有一些小例外)。

Boolean constants
Boolean constants can only be initialized with the keywords false and true. (You cannot use 0 and 1 to represent false and true.)
布尔常量只能使用关键字 false 和 true 进行初始化。 (不能用 0 和 1 来表示 false 和 true。)

Integer literals
Integer literals can be specified in decimal, octal, or hexadecimal notation.
整数可以用十进制、八进制或十六进制表示法指定。

For example:

1
2
3
const byte TheAnswer = 42;
const byte TheAnswerInOctal = 052;
const byte TheAnswerInHex = 0x2A;

Be aware that, if you interpret byte as a number instead of a bit pattern, you may get different results in different languages. For example, for C++, byte maps to unsigned char whereas, for Java, byte maps to byte, which is a signed type.

Note that suffixes to indicate long and unsigned constants (l, L, u, U, used by C++) are illegal:

请注意,如果将字节解释为数字而不是位模式,则在不同语言中可能会得到不同的结果。 例如,对于 C++,字节映射到 unsigned char,而对于 Java,字节映射到 byte,这是一种有符号类型。
请注意,表示长整型和无符号常量(C++ 使用的 l、L、u、U)的后缀是非法的:

1
2
const long Wrong = 0u;          // Syntax error
const long WrongToo = 1000000L; // Syntax error

The value of an integer literal must be within the range of its constant type, as shown in the Built-In Basic Types table; otherwise the compiler will issue a diagnostic.
整数的值必须在其常量类型的范围内,如内置基本类型表所示; 否则编译器将发出诊断信息。

Floating-point literals
Floating-point literals use C++ syntax, except that you cannot use an l or L suffix to indicate an extended floating-point constant; however, f and F are legal (but are ignored).
浮点文字使用 C++ 语法,但不能使用 l 或 L 后缀来指示扩展浮点常量; 然而,f 和 F 是合法的(但被忽略)。
Here are a few examples:

1
2
3
4
5
6
const float P1 = -3.14f;    // Integer & fraction, with suffix
const float P2 = +3.1e-3; // Integer, fraction, and exponent
const float P3 = .1; // Fraction part only
const float P4 = 1.; // Integer part only
const float P5 = .9E5; // Fraction part and exponent
const float P6 = 5e2; // Integer part and exponent

Floating-point literals must be within the range of the constant type (float or double); otherwise, the compiler will issue a diagnostic.
浮点变量必须在常量类型(float 或 double)的范围内; 否则,编译器将发出诊断信息。

String literals
Slice string literals support the same escape sequences as C++, with the exception of hexadecimal escape sequences that are limited to two hexadecimal digits.
Slice字符串变量支持与 C++ 相同的转义序列,但十六进制转义序列除外,该序列仅限于两个十六进制数字。

Escape Sequence Name Corresponding ASCII or Unicode Code Point Notes
\' single quote 0x27
\" double quote 0x22
\? question mark 0x3f
\\ backslash 0x5c
\a audible bell 0x07
\b backspace 0x08
\f form feed 0x0c
\n line feed 0x0a
\r carriage return 0x0d
\t horizontal tab 0x09
\v vertical tab 0x0b
\nnn octal escape sequence 1 to 3 octal digits (0-7) that represent a byte value between 0 and 255
\xnn hexadecimal escape sequence 1 to 2 hexadecimal digits (0-9, a-f, A-F)
\unnnn universal character name U+nnnn Exactly 4 hexadecimal digits. Use the \Unnnnnnnn notation for astral characters.
\Unnnnnnnn universal character name U+nnnnnnnn Exactly 8 hexadecimal digits.

A backslash () followed by another character is simply preserved as is.

Octal and hexadecimal escape sequences can represent ASCII characters (ordinal value 0 to 127) or the UTF-8 encoding of non-ASCII characters.

A string literal can contain printable ASCII characters (including the escape sequences presented above) and non-ASCII characters; non-printable ASCII characters (such as an unescaped tab) are not allowed.

反斜杠 () 后跟另一个字符将按原样保留。
八进制和十六进制转义序列可以表示 ASCII 字符(序数值 0 到 127)或非 ASCII 字符的 UTF-8 编码。
字符串文字可以包含可打印的 ASCII 字符(包括上面介绍的转义序列)和非 ASCII 字符; 不允许使用不可打印的 ASCII 字符(例如未转义的制表符)。

Here are some examples:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const string AnOrdinaryString = "Hello World!";

const string DoubleQuote = "\"";
const string TwoSingleQuotes = "'\'"; // ' and \' are OK
const string QuestionMark = "\?";
const string Backslash = "\\";
const string AudibleBell = "\a";
const string Backspace = "\b";
const string FormFeed = "\f";
const string Newline = "\n";
const string CarriageReturn = "\r";
const string HorizontalTab = "\t";
const string VerticalTab = "\v";

const string OctalEscape = "\007"; // Same as \a
const string HexEscape1 = "\x07"; // Ditto
const string HexEscape2 = "\x41F"; // Same as AF
const string Universal1 = "\u0041"; // Same as A
const string Universal2 = "\U00000041"; // Ditto

const string EuroSign1 = "€"; // Euro sign (U+20AC)
const string EuroSign2 = "\u20AC"; // Euro sign as a short universal character name
const string EuroSign3 = "\U000020ac"; // Euro sign as a long universal character name
const string EuroSign4 = "\xe2\x82\xAC"; // Euro sign in UTF-8 encoding, using hex escape sequences
const string EuroSign5 = "\342\202\254"; // Euro sign in UTF-8 encoding, using octal escape sequences
const string EuroSign6 = "\342\x82\254"; // Euro sign in UTF-8 encoding, using a mix or hex and octal escape sequences
1
const string NullString = null;    // Illegal!

Null strings simply do not exist in Slice and, therefore, do not exist as a legal value for a string anywhere in the Ice platform. The reason for this decision is that null strings do not exist in many programming languages.
空字符串根本不存在于 Slice 中,因此在 Ice 平台中的任何位置都不作为字符串的合法值存在。 做出此决定的原因是许多编程语言中不存在空字符串。

Constant Expressions
A constant definition may also refer to another constant. It is not necessary for both constants to have the same Slice type, but the value of the existing constant must be compatible with the type of the constant being defined.

常量定义也可以引用另一个常量。 两个常量不必具有相同的 Slice 类型,但现有常量的值必须与正在定义的常量的类型兼容。

Consider the examples below:

1
2
3
4
5
const int SIZE = 500;

const int DEFAULT_SIZE = SIZE; // OK
const short SHORT_SIZE = SIZE; // OK
const byte BYTE_SIZE = SIZE; // ERROR

The DEFAULT_SIZE constant is legal because it has the same type as SIZE, and SHORT_SIZE is legal because the value of SIZE (500) is within the range of the Slice short type. However, BYTE_SIZE is illegal because the value of SIZE is outside the range of the byte type.
DEFAULT_SIZE 常量是合法的,因为它与 SIZE 具有相同的类型,SHORT_SIZE 是合法的,因为 SIZE (500) 的值在 Slice Short 类型的范围内。 但是,BYTE_SIZE 是非法的,因为 SIZE 的值超出了字节类型的范围。

1
2
3
4
5
6
7
8
9
10
11
12
13
let future = Python::with_gil(|py| {
// import the module containing the py_sleep function
let example = py.import("example")?;

// calling the py_sleep method like a normal function returns a coroutine
let coroutine = example.call_method0("py_sleep")?;

// convert the coroutine into a Rust future
pyo3_asyncio::into_future(coroutine)
})?;

// await the future
future.await;
1
2
3
4
5
6
7
#[pyfunction]
fn call_rust_sleep(py: Python) -> PyResult<PyObject> {
pyo3_asyncio::async_std::into_coroutine(py, async move {
rust_sleep().await;
Ok(())
})
}
1
2
3
4
5
pyo3_asyncio::tokio::future_into_py(py, async move {
let mut _server_handle = _server.as_ref().lock().await;
_server_handle.entry_direct_hub_server(hub_name).await;
Ok(())
})

Dictionary Syntax and Semantics

A dictionary is a mapping from a key type to a value type.

dictionary是从键类型到值类型的映射

For example:

1
2
3
4
5
6
7
8
9
10
11
module M
{
struct Employee
{
long number;
string firstName;
string lastName;
}

dictionary<long, Employee> EmployeeMap;
}

This definition creates a dictionary named EmployeeMap that maps from an employee number to a structure containing the details for an employee. Whether or not the key type (the employee number, of type long in this example) is also part of the value type (the Employee structure in this example) is up to you — as far as Slice is concerned, there is no need to include the key as part of the value.

此定义创建一个名为 EmployeeMap 的dictionary,该dictionary从员工编号映射到包含员工详细信息的结构。 键类型(员工编号,本例中为 long 类型)是否也是值类型(本例中为 Employee 结构)的一部分取决于您 — 就 Slice 而言,不需要 包含键作为值的一部分。

Dictionaries can be used to implement sparse arrays, or any lookup data structure with non-integral key type. Even though a sequence of structures containing key-value pairs could be used to model the same thing, a dictionary is more appropriate:

dictionary可用于实现稀疏数组或任何具有非整数键类型的查找数据结构。 尽管包含键值对的结构序列可用于对同一事物进行建模,但dictionary更合适:

A dictionary clearly signals the intent of the designer, namely, to provide a mapping from a domain of values to a range of values. (A sequence of structures of key-value pairs does not signal that same intent as clearly.)

dictionary清楚地表明了设计者的意图,即提供从值域到值范围的映射。 (键值对结构的sequence并不能清楚地表明相同的意图。)

At the programming language level, sequences are implemented as vectors (or possibly lists), that is, they are not well suited to model sparsely populated domains and require a linear search to locate an element with a particular value. On the other hand, dictionaries are implemented as a data structure (typically a hash table or red-black tree) that supports efficient searching in O(log n) average time or better.

在编程语言级别,sequences被实现为数组(或可能是list),也就是说,它们不太适合对稀疏填充的域进行建模,并且需要线性搜索来定位具有特定值的元素。 另一方面,dictionary被实现为另一种数据结构(通常是哈希表或红黑树),支持平均时间为 O(log n) 或更好的高效搜索。

Allowable Types for Dictionary Keys and Values

The key type of a dictionary need not be an integral type. For example, we could use the following definition to translate the names of the days of the week:

dictionary的键类型不必是整型。 例如,我们可以使用以下定义来翻译一周中各天的名称:

1
dictionary<string, string> WeekdaysEnglishToGerman;

The server implementation would take care of initializing this map with the key-value pairs Monday-Montag, Tuesday-Dienstag, and so on.

服务器实现将负责使用键值对 Monday-Montag、Tuesday-Dienstag 等初始化该映射。

The value type of a dictionary can be any Slice type. However, the key type of a dictionary is limited to one of the following types:

dictionary的值类型可以是任何 Slice 类型。 但是,字典的键类型仅限于以下类型之一:

Integral types (short, int, long)
bool
byte
string
enum
Structures containing only data members of legal key types

Other complex types, such as dictionaries, and floating-point types (float and double) cannot be used as the key type. Complex types are disallowed because they complicate the language mappings for dictionaries, and floating-point types are disallowed because representational changes of values as they cross machine boundaries can lead to ill-defined semantics for equality.

其他复杂类型,例如dictionary和浮点类型(float 和 double)不能用作键类型。 不允许使用复杂类型,因为它们使dictionary的语言映射变得复杂;并且不允许使用浮点类型,因为跨机器边界时值的表示变化可能会导致平等语义定义不明确。

Sequences are variable-length collections of elements:

Sequences是可变长度的元素集合:

1
2
3
4
module M
{
sequence<Fruit> FruitPlatter;
}

A sequence can be empty — that is, it can contain no elements, or it can hold any number of elements up to the memory limits of your platform.

Sequences can contain elements that are themselves sequences. This arrangement allows you to create lists of lists:

sequence可以是空的,即不包含任何元素,也可以包含任意数量的元素,但不得超过平台的内存限制。

sequence可以包含本身就是sequence的元素。通过这种安排,您可以创建列表的列表:

1
2
3
4
module M
{
sequence<FruitPlatter> FruitBanquet;
}

Sequences are used to model a variety of collections, such as vectors, lists, queues, sets, bags, or trees. (It is up to the application to decide whether or not order is important; by discarding order, a sequence serves as a set or bag.)

Sequences用于对各种集合建模,例如向量、列表、队列、集合、包或树。 (由应用程序决定顺序是否重要;通过丢弃顺序,Sequences充当集合或包。)

Slice supports structures containing one or more named members of arbitrary type, including user-defined complex types. For example:

Slice 支持包含一个或多个任意类型的命名成员的结构,包括用户定义的复杂类型。 例如:

1
2
3
4
5
6
7
8
9
module M
{
struct TimeOfDay
{
short hour; // 0 - 23
short minute; // 0 - 59
short second; // 0 - 59
}
}

As in C++, this definition introduces a new type called TimeOfDay. Structure definitions form a namespace, so the names of the structure members need to be unique only within their enclosing structure.

Data member definitions using a named type are the only construct that can appear inside a structure. It is impossible to, for example, define a structure inside a structure:

与 C++ 中一样,此定义引入了一种称为 TimeOfDay 的新类型。 结构定义形成命名空间,因此结构成员的名称仅在其封闭结构内必须是唯一的。

使用确定类型的数据成员定义是唯一可以出现在结构内部的构造。 例如,不可能在结构内定义结构:

1
2
3
4
5
6
7
8
9
10
struct TwoPoints 
{
struct Point // 非法!
{
short x;
short y;
}
Point coord1;
Point coord2;
}

This rule applies to Slice in general: type definitions cannot be nested (except for modules, which do support nesting). The reason for this rule is that nested type definitions can be difficult to implement for some target languages and, even if implementable, greatly complicate the scope resolution rules. For a specification language, such as Slice, nested type definitions are unnecessary – you can always write the above definitions as follows (which is stylistically cleaner as well):

此规则一般适用于 Slice:类型定义不能嵌套(模块除外,模块支持嵌套)。 此规则的原因是嵌套类型定义对于某些目标语言可能难以实现,并且即使可以实现,也会使范围解析规则变得非常复杂。 对于规范语言,例如 Slice,嵌套类型定义是不必要的 - 您始终可以按如下方式编写上述定义(这在风格上也更清晰):

1
2
3
4
5
6
7
8
9
10
11
struct Point
{
short x;
short y;
}

struct TwoPoints // Legal (and cleaner!)
{
Point coord1;
Point coord2;
}

You can specify a default value for a data member that has one of the following types:

您可以为具有以下类型之一的数据成员指定默认值:

  1. An integral type (byte, short, int, long)
  2. A floating point type (float or double)
  3. string
  4. bool
  5. enum

For example:

1
2
3
4
5
6
7
struct Location
{
string name;
Point pt;
bool display = true;
string source = "GPS";
}

The legal syntax for literal values is the same as for Slice constants, and you may also use a constant as a default value. The language mapping guarantees that data members are initialized to their declared default values using a language-specific mechanism.

字符值的合法语法与 Slice 常量相同,您也可以使用常量作为默认值。 语言映射保证使用特定于语言的机制将数据成员初始化为其声明的默认值。

Enumeration Syntax and Semantics

Slice 枚举类型定义看起来与 C++ 相同:

1
2
3
4
module M
{
enum Fruit { Apple, Pear, Orange }
}

This definition introduces a type named Fruit that becomes a new type in its own right. Slice guarantees that the values of enumerators increase from left to right, so Apple compares less than Pear in every language mapping. By default, the first enumerator has a value of zero, with sequentially increasing values for subsequent enumerators.

A Slice enum type introduces a new namespace scope, so the following is legal:

这个定义引入了一个名为 Fruit 的类型,它本身就成为一种新类型。 Slice 保证枚举数的值从左到右递增,因此 Apple 在每种语言映射中都比 Pear 进行比较。 默认情况下,第一个枚举数的值为零,后续枚举数的值依次增加。

Slice 枚举类型引入了新的命名空间范围,因此以下内容是合法的:

1
2
3
4
5
module M
{
enum Fruit { Apple, Pear, Orange }
enum ComputerBrands { Apple, Dell, HP, Lenovo }
}

The example below shows how to refer to an enumerator from a different scope:

下面的示例展示了如何从不同的范围引用枚举:

1
2
3
4
5
6
7
8
9
10
11
module M
{
enum Color { Red, Green, Blue }
}
module N
{
struct Pixel
{
M::Color c = Blue;
}
}

Slice does not permit empty enumerations.

Slice 不允许空枚举。

In Ice releases prior to Ice 3.7, an enum type did not create a new namespace and its enumerators were in the same namespace as the enum type itself. With these releases, you had to select longer enumerator names to avoid a naming clash.

在 Ice 3.7 之前的 Ice 版本中,枚举类型不会创建新的命名空间,并且其枚举器与枚举类型本身位于同一命名空间中。 在这些版本中,您必须选择更长的枚举器名称以避免命名冲突。

Custom Enumerator Values

Slice also permits you to assign custom values to enumerators:

Slice 还允许您为枚举器分配自定义值:

1
2
const int PearValue = 7;
enum Fruit { Apple = 0, Pear = PearValue, Orange }

Custom values must be unique and non-negative, and may refer to Slice constants of integer types. If no custom value is specified for an enumerator, its value is one greater than the enumerator that immediately precedes it. In the example above, Orange has the value 8.

The maximum value for an enumerator value is the same as the maximum value for int, 2 31 - 1.

Slice does not require custom enumerator values to be declared in increasing order:

自定义值必须是唯一且非负的,并且可以引用整数类型的 Slice 常量。 如果没有为枚举器指定自定义值,则其值比紧邻其前面的枚举器大 1。 在上面的示例中,Orange的值为 8。

枚举值的最大值与 int 的最大值相同,即 2^31 - 1。

Slice 不需要按升序声明自定义枚举值:

1
enum Fruit { Apple = 5, Pear = 3, Orange = 1 }   // 合法的

Note however that when there is an inconsistency between the declaration order and the numerical order of the enumerators, the behavior of comparison operations may vary between language mappings.

但请注意,当声明顺序与枚举数的数字顺序不一致时,比较操作的行为可能会因语言映射而异。

For an application that is still using version 1.0 of the Ice encoding, changing the definition of an enumerated type may break backward compatibility with existing applications. For more information, please refer to the encoding rules for enumerators.

对于仍在使用 Ice 编码 1.0 版的应用程序,更改枚举类型的定义可能会破坏与现有应用程序的向后兼容性。 更多信息请参考枚举数的编码规则。

Basic Types

Built-In Basic Types
Slice provides a number of built-in basic types, as shown in this table:

内置基本类型
Slice 提供了许多内置的基本类型,如下表所示:

Type Range of Mapped Type Size of Mapped Type
bool false or true ≥ 1bit
byte -128-127 or 0-255 ≥ 8 bits
short -2^15 to 2^15 -1 ≥ 16 bits
int -2^31 to 2^31 -1 ≥ 32 bits
long -2^63 to 2^63 -1 ≥ 64 bits
float IEEE single-precision ≥ 32 bits
double IEEE double-precision ≥ 64 bits
string All Unicode characters Variable-length

The range depends on whether byte maps to a signed or an unsigned type.

范围取决于字节映射到有符号类型还是无符号类型。

All the basic types (except byte) are subject to changes in representation as they are transmitted between clients and servers. For example, a long value is byte-swapped when sent from a little-endian to a big-endian machine. However, these changes are transparent to the programmer and do exactly what is required.

所有基本类型(字节除外)在客户端和服务器之间传输时都会发生表示形式的变化。 例如,长值在从小端机器发送到大端机器时会进行字节交换。 然而,这些更改对程序员来说是透明的,并且完全按照要求进行。

Integer Types

Slice provides integer types short, int, and long, with 16-bit, 32-bit, and 64-bit ranges, respectively. Note that, on some architectures, any of these types may be mapped to a native type that is wider. Also note that no unsigned types are provided. (This choice was made because unsigned types are difficult to map into languages without native unsigned types, such as Java. In addition, the unsigned integers add little value to a language.

Slice 提供整数类型short、int 和long,分别具有16 位、32 位和64 位范围。 请注意,在某些体系结构上,这些类型中的任何一个都可以映射到更宽的本机类型。 另请注意,不提供无符号类型。 (做出这个选择是因为无符号类型很难映射到没有本机无符号类型的语言,例如 Java。此外,无符号整数对语言几乎没有增加价值。

Floating-Point Types

These types follow the IEEE specification for single- and double-precision floating-point representation [1]. If an implementation cannot support IEEE format floating-point values, the Ice run time converts values into the native floating-point representation (possibly at a loss of precision or even magnitude, depending on the capabilities of the native floating-point format).

这些类型遵循单精度和双精度浮点表示的 IEEE 规范 [1]。 如果实现无法支持 IEEE 格式浮点值,Ice run time 会将值转换为本机浮点表示形式(可能会损失精度甚至幅度,具体取决于本机浮点格式的功能)。

Strings

Slice strings use the Unicode character set and are encoded using UTF-8 when transmitted between clients and servers.

Slice字符串使用 Unicode 字符集,并在客户端和服务器之间传输时使用 UTF-8 进行编码。

Booleans

Boolean values can have only the values false and true. Language mappings use the corresponding native boolean type if one is available.

布尔值只能有 false 和 true 值。 语言映射使用相应的本机布尔类型(如果可用)。

Bytes

The Slice type byte is an (at least) 8-bit type that is guaranteed not to undergo any changes in representation as it is transmitted between address spaces. This guarantee permits exchange of binary data such that it is not tampered with in transit. All other Slice types are subject to changes in representation during transmission.

Slice 类型字节是(至少)8 位类型,保证在地址空间之间传输时不会发生任何表示形式的变化。 此保证允许交换二进制数据,使其在传输过程中不会被篡改。 所有其他切片类型在传输过程中的表示形式都会发生变化。

Modules Reduce Clutter

A common problem in large systems is pollution of the global namespace: over time, as isolated systems are integrated, name clashes become quite likely. Slice provides the module construct to alleviate this problem:

大型系统中的一个常见问题是全局名称空间的污染:随着时间的推移,随着孤立的系统的集成,名称冲突变得很可能。 Slice 提供了模块构造来缓解这个问题:

1
2
3
4
5
6
7
8
9
10
11
module ZeroC 
{
module Client
{
// Definitions here...
}
module Server
{
// Definitions here...
}
}

A module can contain any legal Slice construct, including other module definitions. Using modules to group related definitions together avoids polluting the global namespace and makes accidental name clashes quite unlikely. (You can use a well-known name, such as a company or product name, as the name of the outermost module.)

模块可以包含任何合法的 Slice 构造,包括其他模块定义。 使用模块将相关定义分组在一起可以避免污染全局名称空间,并且不太可能发生意外的名称冲突。 (您可以使用众所周知的名称,例如公司或产品名称,作为最外层模块的名称。)

Modules are Mandatory

Slice requires all definitions to be nested inside a module, that is, you cannot define anything other than a module at global scope. For example, the following is illegal:

Slice 要求所有定义都嵌套在模块内,也就是说,您不能在全局范围内定义除模块之外的任何内容。 例如,以下行为是非法的:

1
2
3
4
interface I   // Error: only modules can appear at global scope
{
// ...
}

Definitions at global scope are prohibited because they cause problems with some implementation languages (such as Python, which does not have a true global scope).

禁止在全局范围内进行定义,因为它们会导致某些实现语言(例如 Python,它没有真正的全局范围)出现问题。

Throughout the Ice manual, you will occasionally see Slice definitions that are not nested inside a module. This is to keep the examples short and free of clutter. Whenever you see such a definition, assume that it is nested in module M.

在整个 Ice 手册中,您偶尔会看到未嵌套在模块内的 Slice 定义。 这是为了保持示例简短且整洁。 每当您看到这样的定义时,请假设它嵌套在模块 M 中。

Reopening Modules

Modules can be reopened:

可以重新打开模块:

1
2
3
4
5
6
7
8
9
10
11
module ZeroC
{
// Definitions here...
}

// Possibly in a different source file:

module ZeroC // OK, reopened module
{
// More definitions here...
}

Reopened modules are useful for larger projects: they allow you to split the contents of a module over several different source files. The advantage of doing this is that, when a developer makes a change to one part of the module, only files dependent on the changed part need be recompiled (instead of having to recompile all files that use the module).

重新打开的模块对于较大的项目很有用:它们允许您将模块的内容拆分为多个不同的源文件。 这样做的好处是,当开发人员对模块的一部分进行更改时,只需重新编译依赖于更改部分的文件(而不需要重新编译使用该模块的所有文件)。

Module Mapping

Modules map to a corresponding scoping construct in each programming language. (For example, for C++ and C#, Slice modules map to namespaces whereas, for Java, they map to packages.) This allows you to use an appropriate C++ using or Java import declaration to avoid excessively long identifiers in your source code.

模块映射到每种编程语言中相应的作用域构造。 (例如,对于 C++ 和 C#,Slice 模块映射到命名空间,而对于 Java,它们映射到包。)这允许您使用适当的 C++ using 或 Java import 声明来避免源代码中的标识符过长。

The Ice Module

APIs for the Ice run time, apart from a small number of language-specific calls that cannot be expressed in Ice, are defined in the Ice module. In other words, most of the Ice API is actually expressed as Slice definitions. The advantage of doing this is that a single Slice definition is sufficient to define the API for the Ice run time for all supported languages. The respective language mapping rules then determine the exact shape of each Ice API for each implementation language.

We will incrementally explore the contents of the Ice module throughout this manual.

Ice 运行时的 API,除了少数无法在 Ice 中表达的特定于语言的调用之外,均在 Ice 模块中定义。 换句话说,大部分 Ice API 实际上都是表达为 Slice 定义的。 这样做的优点是单个 Slice 定义足以为所有支持的语言定义 Ice 运行时的 API。 然后,相应的语言映射规则确定每种实现语言的每个 Ice API 的确切形态。

我们将在本手册中逐步探索 Ice 模块的内容。