埃菲尔铁塔:最好的方式来比较类型而不会引起嘘声
Eiffel: best way to compare types without getting a catcall
有一个 Catcall 试图比较 2 种类型,我该怎么做才能避免通过另一个非专用方法(例如字符串、class_id 或类似的东西)?
SIT_UTIL
class_name_lowercase (a_string: STRING): STRING
-- a copy lowercased and pruned from preceding '!'
do
Result := a_string
if Result.index_of('!', 1) = 1 then
Result := Result.substring (2, Result.count)
Result.to_lower
else
Result := Result.as_lower
end
ensure
instance_free: class
end
CLIENT_CLASS
relationship_from_secondary_type_equal (a_type: like relationships.item.secondary_type): detachable like relationships.item
-- Returns first instance of found relationship secondary type which equals given one
do
across
relationships as l_rel
until
Result /= Void
loop
-- if attached (a_type / l_rel.item.secondary_type) then -- Don't want conformance but equality
-- if attached (a_type.is_equal (l_rel.item.secondary_type)) then -- tried but as is_equal needs a like Current => Catcall
-- if attached (a_type.equal (a_type, l_rel.item.secondary_type)) then -- Catcall because b signature is like a
if {SIT_UTIL}.class_name_lowercase (a_type).is_equal({SIT_UTIL}.class_name_lowercase (l_rel.item.secondary_type)) then
Result := l_rel.item
end
end
check
not_found_relationship: Result /= Void
end
end
一致性属性是反对称的,即如果A→B和B→A,那么 A = B。因此,两种类型是相等的,它们相互符合:
a_type.conforms_to (l_rel.item.secondary_type) and
l_rel.item.secondary_type.conforms_to (a_type)
(尽管 conforms_to
比较的是对象的类型而不是对象本身,但是上面的表达式仍然可以,因为由于一致性规则 A = B 当且仅当如果 TYPE [A] = TYPE [B] 当 A 和 B 本身就是类型。)
如果其中一种类型是附加的,另一种是可拆卸的,您仍然可能希望将它们作为相等进行比较。在这种情况下,可以使用以下代码:
is_conforming (a_type, l_rel.item.secondary_type) and
is_conforming (l_rel.item.secondary_type, a_type)
比较谓词忽略附件标记的地方:
is_conforming (t1, t2: TYPE [detachable ANY]): BOOLEAN
do
Result :=
({REFLECTOR}.type_of_type ({REFLECTOR}.detachable_type (t1.type_id))).conforms_to
({REFLECTOR}.type_of_type ({REFLECTOR}.detachable_type (t2.type_id)))
end
有一个 Catcall 试图比较 2 种类型,我该怎么做才能避免通过另一个非专用方法(例如字符串、class_id 或类似的东西)?
SIT_UTIL
class_name_lowercase (a_string: STRING): STRING
-- a copy lowercased and pruned from preceding '!'
do
Result := a_string
if Result.index_of('!', 1) = 1 then
Result := Result.substring (2, Result.count)
Result.to_lower
else
Result := Result.as_lower
end
ensure
instance_free: class
end
CLIENT_CLASS
relationship_from_secondary_type_equal (a_type: like relationships.item.secondary_type): detachable like relationships.item
-- Returns first instance of found relationship secondary type which equals given one
do
across
relationships as l_rel
until
Result /= Void
loop
-- if attached (a_type / l_rel.item.secondary_type) then -- Don't want conformance but equality
-- if attached (a_type.is_equal (l_rel.item.secondary_type)) then -- tried but as is_equal needs a like Current => Catcall
-- if attached (a_type.equal (a_type, l_rel.item.secondary_type)) then -- Catcall because b signature is like a
if {SIT_UTIL}.class_name_lowercase (a_type).is_equal({SIT_UTIL}.class_name_lowercase (l_rel.item.secondary_type)) then
Result := l_rel.item
end
end
check
not_found_relationship: Result /= Void
end
end
一致性属性是反对称的,即如果A→B和B→A,那么 A = B。因此,两种类型是相等的,它们相互符合:
a_type.conforms_to (l_rel.item.secondary_type) and
l_rel.item.secondary_type.conforms_to (a_type)
(尽管 conforms_to
比较的是对象的类型而不是对象本身,但是上面的表达式仍然可以,因为由于一致性规则 A = B 当且仅当如果 TYPE [A] = TYPE [B] 当 A 和 B 本身就是类型。)
如果其中一种类型是附加的,另一种是可拆卸的,您仍然可能希望将它们作为相等进行比较。在这种情况下,可以使用以下代码:
is_conforming (a_type, l_rel.item.secondary_type) and
is_conforming (l_rel.item.secondary_type, a_type)
比较谓词忽略附件标记的地方:
is_conforming (t1, t2: TYPE [detachable ANY]): BOOLEAN
do
Result :=
({REFLECTOR}.type_of_type ({REFLECTOR}.detachable_type (t1.type_id))).conforms_to
({REFLECTOR}.type_of_type ({REFLECTOR}.detachable_type (t2.type_id)))
end