这本书在过程重载方面自相矛盾吗
does this book contradict itself on procedure overloading
DECLARE
TYPE DateTyp IS TABLE OF DATE INDEX BY PLS_INTEGER;
TYPE NumTyp IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
hiredate DateTyp;
sal NumTyp;
PROCEDURE initial(tab OUT DateTyp, n INTEGER) IS
BEGIN
FOR i IN 1..n LOOP
tab(i) := SYSDATE;
END LOOP;
END initial;
PROCEDURE initial(tab OUT NumTyp, n INTEGER) IS
BEGIN
FOR i IN 1..n LOOP
tab(i) := 0.0;
END LOOP;
END initial;
BEGIN
Initial(hiredate, 50); --calls first(DateTyp) version
initial(sal, 100); --calls second(NumTyp) version
END;
他们给出了这个例子(他们说这是有效的)来说明子程序重载..."They differ only in their parameter types."
但随后他们给出了这个限制指南:
You cannot overload two subprograms that differ only in their subtypes. For example, you cannot overload the following two subprograms:
DECLARE
...
PROCEDURE withdraw(amount INTEGER) IS
BEGIN ... END;
PROCEDURE withdraw(amount REAL) IS
BEGIN ... END;
我没有看到或理解什么....他们通过仅更改参数类型来给出示例,他们说这是有效的(第一个示例)....然后他们说这是不允许的
第一个示例仅将制表符从 DateTyp 更改为 NumTyp....然后第二个示例仅将金额从 INTEGER 更改为 REAL...
PL/SQL 文档有一个有用的附录,我认为它有助于解释差异。 Find it here.
它将支持的数据类型分成系列。 DATE、NUMBER 和 VARCHAR2 是不同的系列。具有不同数据类型系列(例如 DATE 和 VARCHAR2)参数的重载过程是不同的,因此是允许的。具有来自相同数据类型系列(REAL 和 INTEGER)的参数的重载过程没有区别,因为它们都是 NUMBER 类型。因此,它们是不允许的。
基本上,这个调用引用了第二个过程的哪个实例?
withdraw(200);
谁也说不准。
这两个例子并不矛盾。 DateType 是 TABLE OF DATE; NumTyp 是一个 TABLE OF NUMBER。这些是截然不同的类型。 INTEGER 和 REAL 都是 NUMBER 的子类型,在 STANDARD 包中定义为:
type NUMBER is NUMBER_BASE;
subtype FLOAT is NUMBER; -- NUMBER(126)
subtype REAL is FLOAT; -- FLOAT(63)
subtype "DOUBLE PRECISION" is FLOAT;
subtype INTEGER is NUMBER(38,0);
所以 INTEGER 是 NUMBER 的直接子类型,而 REAL 是 FLOAT 的子类型,而 FLOAT 是 NUMBER 的子类型。因此,INTEGER 和 REAL 都是 NUMBER 的子类型,因此不能作为重载子程序之间的唯一区别。
DECLARE
TYPE DateTyp IS TABLE OF DATE INDEX BY PLS_INTEGER;
TYPE NumTyp IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
hiredate DateTyp;
sal NumTyp;
PROCEDURE initial(tab OUT DateTyp, n INTEGER) IS
BEGIN
FOR i IN 1..n LOOP
tab(i) := SYSDATE;
END LOOP;
END initial;
PROCEDURE initial(tab OUT NumTyp, n INTEGER) IS
BEGIN
FOR i IN 1..n LOOP
tab(i) := 0.0;
END LOOP;
END initial;
BEGIN
Initial(hiredate, 50); --calls first(DateTyp) version
initial(sal, 100); --calls second(NumTyp) version
END;
他们给出了这个例子(他们说这是有效的)来说明子程序重载..."They differ only in their parameter types."
但随后他们给出了这个限制指南:
You cannot overload two subprograms that differ only in their subtypes. For example, you cannot overload the following two subprograms:
DECLARE
...
PROCEDURE withdraw(amount INTEGER) IS
BEGIN ... END;
PROCEDURE withdraw(amount REAL) IS
BEGIN ... END;
我没有看到或理解什么....他们通过仅更改参数类型来给出示例,他们说这是有效的(第一个示例)....然后他们说这是不允许的
第一个示例仅将制表符从 DateTyp 更改为 NumTyp....然后第二个示例仅将金额从 INTEGER 更改为 REAL...
PL/SQL 文档有一个有用的附录,我认为它有助于解释差异。 Find it here.
它将支持的数据类型分成系列。 DATE、NUMBER 和 VARCHAR2 是不同的系列。具有不同数据类型系列(例如 DATE 和 VARCHAR2)参数的重载过程是不同的,因此是允许的。具有来自相同数据类型系列(REAL 和 INTEGER)的参数的重载过程没有区别,因为它们都是 NUMBER 类型。因此,它们是不允许的。
基本上,这个调用引用了第二个过程的哪个实例?
withdraw(200);
谁也说不准。
这两个例子并不矛盾。 DateType 是 TABLE OF DATE; NumTyp 是一个 TABLE OF NUMBER。这些是截然不同的类型。 INTEGER 和 REAL 都是 NUMBER 的子类型,在 STANDARD 包中定义为:
type NUMBER is NUMBER_BASE;
subtype FLOAT is NUMBER; -- NUMBER(126)
subtype REAL is FLOAT; -- FLOAT(63)
subtype "DOUBLE PRECISION" is FLOAT;
subtype INTEGER is NUMBER(38,0);
所以 INTEGER 是 NUMBER 的直接子类型,而 REAL 是 FLOAT 的子类型,而 FLOAT 是 NUMBER 的子类型。因此,INTEGER 和 REAL 都是 NUMBER 的子类型,因此不能作为重载子程序之间的唯一区别。