以下程序 (main.adb) 将无法编译,并出现错误:
main.adb:10:15: expected private type "ThreadName" defined at config.ads:5
main.adb:10:15: found private type "Ada.Strings.Unbounded.Unbounded_String"
main.adb:11:45: expected private type "Ada.Strings.Unbounded.Unbounded_String"
main.adb:11:45: found private type "ThreadName" defined at config.ads:5
Run Code Online (Sandbox Code Playgroud)
然而,当我添加一个“使用配置;” 条款并删除配置。在 main.adb 中 MyName 声明的前缀,它编译干净并正常工作。我明白使用“use”子句只是为了让我避免使用名称空间前缀,但它似乎还有很多作用。谁能解释一下?
文件 config.ads 包含
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
package Config is
type ThreadName is new Unbounded_String;
end Config;
Run Code Online (Sandbox Code Playgroud)
我的 main.adb 包含:
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Config;
procedure Main is
MyName : Config.ThreadName;
begin
MyName := To_Unbounded_String ("Chris");
Put_Line ( "The name is: " & To_String (MyName));
end Main;
Run Code Online (Sandbox Code Playgroud)
Use 还使对包中定义的类型的隐式定义的操作可见......在此示例中包括 To_Unbounded_String,反之亦然。
还有 Use Type 使操作可见,而不会用包中的所有内容污染命名空间;但它只公开运算符(+、-、= 等),而
with Config;
use all type Config.Threadname;
Run Code Online (Sandbox Code Playgroud)
将使类型、运算符和其他子程序可见,Config.Threadname而不会暴露包中的任何其他内容。
use 子句使包的内容在 use 子句的范围内可见。在上面的示例中,您“使用”配置但不“使用”配置。另一方面,Ada.Strings.Unbounded 有一个“use”子句,使其类型、常量和子程序在 Main 范围内可见。
procedure Main is
MyName : Config.ThreadName;
begin
MyName := To_Unbounded_String ("Chris");
Put_Line ( "The name is: " & To_String (MyName));
end Main;
Run Code Online (Sandbox Code Playgroud)
MyName 被声明为 Config.ThreadName 类型的实例。ThreadName 被声明为与 Ubounded_String 不同的类型。因此,在 Ada.Strings.Unbounded 包中可见的操作不适用于 ThreadName 的实例。如果您“使用” Config,编译器将对适用于类型 ThreadName 的所有子程序可见,并且能够根据参数类型和函数返回类型确定要调用哪个“To_Unbounded_String”函数。
“use”子句的副作用是减少编写 package_name.subprogram 的需要,但其主要目的是使包的公共内容在使用“use”子句的编译单元范围内可见。