无法为受保护类型写入聚合
Can’t write aggregate for protected type
我有以下功能
function Allocate(V : Value_Type; N : access Node) return access Node is
begin
return new Node'(Value => V, Next => N);
end Allocate;
在编译时,GNAT 抱怨期望访问 Node,却找到了复合类型。这好像坏了。
节点是:
protected type Node is
--Various routines
private
Value : Value_Type;
Next : access Node;
end Node;
我已经恢复到非任务类型,并且没有确切的错误消息。这是我见过无数次的例子,例如,仅使用:
return (Value => V, Next => N);
或类似。使用"new Type'()".
的时候没见过
Value
和 Next
唯一可见的地方(当然,Node
规范的私有部分除外)是它们自己的 Node
的 body.
我看不到 Node
中 Allocate
的写法。我放弃了
function Allocate (V : Boolean) return access Node is
begin
return N : access Node do
N := new Node;
N.Next := Node'Access;
N.Value := V;
end return;
end Allocate;
一路上收到消息,包括
protected function cannot modify protected object
protected type cannot be used as type mark within its own spec or body
(so you can't say Node'Access
)
invisible selector "Value" for type “Node"
所以我认为您需要使用某种包装器。
正确,没有针对受保护类型的聚合。正如西蒙在他的回答中所说,受保护字段是私有的,并且仅在受保护类型的主体内可见(或者可能稍后在受保护类型的私有部分中可见)。外界根本看不到田野。所以你必须添加一个受保护的过程来设置字段:
protected type Node is
--Various routines
procedure Set_Value(V : Value_Type);
procedure Set_Next(N : access Node);
private
Value : Value_Type;
Next : access Node;
end Node;
并在您的 Allocate
:
中调用程序
function Allocate (V : Boolean; N : access Node) return access Node is
New_Node : access Node;
begin
New_Node := new Node;
New_Node.Set_Value (V);
New_Node.Set_Next (N);
return New_Node;
end Allocate;
(或者像 Simon 的回答一样使用扩展 return——我认为它会起作用。)
注意:我没有测试过这个。
另一种可能性,如果 Value
和 Next
在受保护对象的整个生命周期中永远不会改变,则使用判别式:
protected type Node (Value : Value_Type; Next : access Node) is ...
现在你可以说
return new Node(Value => V, Next => N);
请注意,此语法中没有刻度线!不过,我还没有对此进行测试,所以我不确定它是否会起作用。我认为在判别表中引用相同类型是可以接受的,但我不确定。
我有以下功能
function Allocate(V : Value_Type; N : access Node) return access Node is
begin
return new Node'(Value => V, Next => N);
end Allocate;
在编译时,GNAT 抱怨期望访问 Node,却找到了复合类型。这好像坏了。
节点是:
protected type Node is
--Various routines
private
Value : Value_Type;
Next : access Node;
end Node;
我已经恢复到非任务类型,并且没有确切的错误消息。这是我见过无数次的例子,例如,仅使用:
return (Value => V, Next => N);
或类似。使用"new Type'()".
的时候没见过Value
和 Next
唯一可见的地方(当然,Node
规范的私有部分除外)是它们自己的 Node
的 body.
我看不到 Node
中 Allocate
的写法。我放弃了
function Allocate (V : Boolean) return access Node is
begin
return N : access Node do
N := new Node;
N.Next := Node'Access;
N.Value := V;
end return;
end Allocate;
一路上收到消息,包括
protected function cannot modify protected object
protected type cannot be used as type mark within its own spec or body
(so you can't sayNode'Access
)
invisible selector "Value" for type “Node"
所以我认为您需要使用某种包装器。
正确,没有针对受保护类型的聚合。正如西蒙在他的回答中所说,受保护字段是私有的,并且仅在受保护类型的主体内可见(或者可能稍后在受保护类型的私有部分中可见)。外界根本看不到田野。所以你必须添加一个受保护的过程来设置字段:
protected type Node is
--Various routines
procedure Set_Value(V : Value_Type);
procedure Set_Next(N : access Node);
private
Value : Value_Type;
Next : access Node;
end Node;
并在您的 Allocate
:
function Allocate (V : Boolean; N : access Node) return access Node is
New_Node : access Node;
begin
New_Node := new Node;
New_Node.Set_Value (V);
New_Node.Set_Next (N);
return New_Node;
end Allocate;
(或者像 Simon 的回答一样使用扩展 return——我认为它会起作用。)
注意:我没有测试过这个。
另一种可能性,如果 Value
和 Next
在受保护对象的整个生命周期中永远不会改变,则使用判别式:
protected type Node (Value : Value_Type; Next : access Node) is ...
现在你可以说
return new Node(Value => V, Next => N);
请注意,此语法中没有刻度线!不过,我还没有对此进行测试,所以我不确定它是否会起作用。我认为在判别表中引用相同类型是可以接受的,但我不确定。