编写此功能时:
let make_new_instance class_name = new class_name
我得到错误“unbound class class_name”,但是,这只是一个函数定义,而不是函数调用。如何延迟“new”以便在调用函数之前不会尝试构造对象?
答案 0 :(得分:4)
你不能在OCaml中这样做,OCaml是一种静态类型的语言。必须在new
静态指定类,并且不能将其用作函数应用程序的参数。 (new
甚至不是一个函数,而是一个特殊形式new <classname>
。)
参数化类的一种方法是使用仿函数:
module A = struct
class c = object
method x = 1
end
end
module Make(A : sig class c : object method x : int end end) = struct
let make_new_instance () = new A.c
end
module MakeA = Make(A)
但我担心这远不是你想要的。
答案 1 :(得分:1)
这不是你在OCaml中可以做的事情。一种看待这种情况的方法是考虑将传递给函数的内容。类名是类型,而不是值。另一种方法是注意函数只能返回一种类型的值。不同的类有不同的类型。
答案 2 :(得分:0)
您是否尝试将class_name
参数更改为单位?
let make_new_class_name () = new class_name
答案 3 :(得分:0)
OCaml中的类似蓝图,但是为了创建某些东西,通常不是从蓝图开始,而是去工厂。因此,如果您需要一个创建某个类实例的工厂,那么就可以完成:
class blue_print x y = object ... end
let create_instance = new blue_print
let factory instance_maker x y = instance_maker x y
当然,所有这些都没有多大意义,因为示例非常简单,但如果它与某些注册表相关联,那么您将存储instace_maker
s,那么您将获得一个抽象工厂< / p>
答案 4 :(得分:0)
我收到错误
unbound class class_name
,但这只是一个函数定义,而不是函数调用。如何延迟&#34; new&#34;这样在调用函数之前它不会尝试构造一个对象吗?
你得到的错误来自class_name
这里是函数参数的名称这一事实,但你试着让它带有一个类的名字。在PERL,PHP或其他类似语言的语言中,您可以在运行时访问符号表,从而可以定义新函数,新类,新变量,并在变量中引用它们。例如,在PHP中,代码为:
<?php
function foo($var){ echo ${$var};}
$bar = "foo";
$bar($bar);
会呈现:
"Function"
通过变量foo
调用函数$bar
。
在OCaml中,您无法使用值名称执行此操作,在您的确切情况下,语法严格要求在关键字new
之后使用类名称(否则您将遇到动态语言中通常遇到的问题,即,如何检查变量内容是否真的是一个类) - 杰弗里Scoffield就在那里。但是,作为一种函数式语言,通常的方法是传递函数,并将它们应用于其他函数中的参数:
class foo () = object
method m = "foo"
end
class bar () = object
method m = "bar"
end
上面的两个类都有相同的类类型,并且期望使用相同的参数来创建它们的实例,因此您可以互换使用它们而不输入问题。
let mk_instance toggle : object method m : string end =
if toggle
then new foo ()
else new bar ()
函数mk_instance
将生成foo
的实例或bar
的实例,具体取决于toggle
的值。
您可以通过创建包含foo
和bar
s实例化的函数来使用它,然后传递它们:
let mk_foo = new foo
let mk_bar = new bar
let mk_instance mk : object method m : string end = mk ()
上面的内容很简单,但您可能会设想具有更多相关类定义的案例,并且通过闭包,始终可以对齐函数签名以使其更容易,或者将它们嵌入到求和类型中以指示不同的可能性。