- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在将 PHP 项目转换为 Hack 项目,但遇到了一些障碍。我想做的是将 IoC 容器从 PHP 重写为 Hack,但在让所有内容通过 Hack 类型检查器工具时遇到了一些麻烦。
所以基本上我拥有的是一个容器,可以让您将字符串注册到闭包映射。这个想法是闭包包含实例化类的逻辑。容器还存储它创建的实例,并且还允许您强制创建新实例。这是我的容器代码:
<?hh // strict
class Container {
private Map<string, mixed> $instances = Map {};
private Map<string, (function (Container): mixed)> $registered = Map {};
public function register(string $alias, (function (Container): mixed) $closure): void
{
$this->registered[$alias] = $closure;
}
public function get(string $alias): ?mixed
{
if (!$this->registered->contains($alias)) {
return null;
}
$instance = $this->instances->get($alias);
if ($instance !== null) {
return $instance;
}
$closure = $this->registered->get($alias);
if ($closure !== null) {
$this->instances->set($alias, $closure($this));
}
return $this->instances->get($alias);
}
public function getNew(string $alias): ?mixed
{
if (!$this->registered->contains($alias)) {
return null;
}
$closure = $this->registered->get($alias);
return ($closure !== null) ? $closure($this) : null;
}
}
这个类本身似乎通过了类型检查器,但是当使用 Container::get()
或 Container::getNew()
时,由于返回的是类型 mixed
,当我尝试对这些返回的对象执行方法时,它会抛出此错误:
You are trying to access the member x but this is not an object, it is a mixed value
现在我知道这是有道理的,因为混合显然允许非对象,所以我必须确保将此类代码包装在 is_object()
中,但是这样做似乎并不可行抑制类型检查器中的错误。有没有更好的方法来确认某个东西是 Hack 中的对象,并且类型检查器能够理解?
此外,这个 IoC 容器类严重依赖于混合类型,这对我来说有点难看。必须确保其返回值在运行时是对象也是不理想的。我有更好的方法可以做到这一点吗?我确实尝试过将混合更改为接口(interface)(如 IContainable 或其他东西)的想法,并且让我想要存储在容器中的任何类实现此功能,但类型检查器提示 IContainable 接口(interface)不包含该方法我试图调用从容器返回的对象(因此在代码中的同一点出现错误,但原因不同)。也许我用这种方法已经接近成功了?
感谢您的帮助。
最佳答案
Is there a better way to confirm something is an object in Hack, that the type checker will understand?
您可能想通过 instanceof
检查特定实例。例如:(警告,代码直接输入浏览器)
<?hh // strict
class C {
public function f(): void {}
}
function f(): mixed {
return new C();
}
function g(): void {
$c = f();
// $c->f() won't work out here, $c is mixed
if ($c instanceof C) {
$c->f(); // This works now
}
}
另请注意,您不需要 ?mixed
,这是多余的 - 只需使用 mixed
。 (因为 mixed 可以是任何东西,所以它也可以是 null。当你编写 ?mixed
时生成错误是我在某些时候要做的事情列表中的。:))
Also, this IoC container class relies heavily on the mixed type, which is a bit ugly to me.
你的直觉很好。在 Facebook,我们发现在大多数情况下,我们想要输入混合类型的内容,要么 1) 我们应该编写更具体的类型,要么 2) 代码的结构非常简单很糟糕,我们应该重新考虑如何构建它以更好地打字。
也许您应该使用更具体的类型。正如您所指出的,使用界面会有所帮助。如果事实证明您需要做的大多数事情实际上都是该接口(interface)的一部分,并且您只是偶尔需要做其他事情,那么您可以将其与上述 instanceof
功能结合起来。您可能还想看看using generics ,这可能有意义也可能没有意义,具体取决于您使用 Container
的具体方式。如果 Container 被实例化多次,每次实例化不同的特定子类或接口(interface),那么泛型可能正是您想要的。如果它是单例,那么也许不是。 (此外,虽然您没有在此处显示它,但如果 Container
以任何方式与其保存的类进行交互,您可能需要 constraint on the generic 。)
但我怀疑您遇到这个问题是由于结构性问题。当我遇到这个问题时,我会想到以下一些事情:为什么首先需要围绕实例化类进行这一抽象层——它提供什么功能,以及您能否使该功能同构(即,可打字) )并与异构类实例化问题分开?暂时忽略正式类型(即,如果您是用普通 PHP 编写的),使用 Container
的类如何知道它得到了正确的东西?必须对进出的内容有一定的了解,无论调用代码中的内容是非正式的还是其他方式,否则这首先就行不通!考虑一下这些信息是在哪里以及如何编码的,然后看看是否可以找到一种方法将其明确化。
希望这有帮助!如果我可以澄清任何事情,请在评论中告诉我。当然,请随意继续问这样的问题,许多 FB Hack 工程师以及知识渊博的社区成员都密切关注“hacklang”标签:)(我们真的很高兴人们正在尝试 Hack BTW!希望你是享受它。)
关于hacklang - 在 Hack 中编写 IoC 容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23580272/
我有以下形状: const type A = shape( 'b' => dict, ); 如何用空字典创建这个形状?例如从这个函数 function getA(): A { return s
因此,Hacklang 推出了一种新的、奇特的类型系统,在使用可为空变量之前必须对其进行检查。我想知道的是,您能否实现类似线性类型的功能,静态强制函数调用的顺序,常见的示例是在读取文件之前打开文件?在
假设我有这样的形状 $something = shape( 'some_key' => ..., 'another_key' => ..., ... ); 如何迭代形状的每个字段?我正在寻
我决定开始一个新项目来进入 hacklang,在解决了一些我最初遇到的从 php 习惯过渡的问题之后,我遇到了以下错误: Unbound name: str_replace Unbound name:
如何从异常对象获取堆栈跟踪?给定异常,我特别希望提取调用堆栈和行号。 我试过这个: function do_it(int $x, int $y): void { try { $result
Hacklang 可能仍然相对较新,但是否有任何框架(例如 MVC)对其进行了详细记录?我偶然发现了 Fastuc或 Hack-mvc但他们似乎还没有准备好,而且文档非常稀缺; 有什么想法吗 ? 非常
Hack Set 有一个difference 方法,但我没有看到名为intersect 或任何类似方法的方法。 如何得到两个集合的交集? $set1 = Set { 'a', 'x' }; $set2
最近,Facebook 发布了一种名为 Hacklang 的新语言,它通过 HHVM 编译为机器码。 所以我想知道,Hacklang 仅仅是一种状态语言吗? 谢谢。 最佳答案 PHP 是无状态的,除非
我正在实现一个返回 Awaitable 的函数- 但目前,我只想返回一个占位符值。 我该如何做到这一点? 在 rust 中,我会调用 unimplemented!() 宏——在 java/python
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve th
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve th
举个例子,假设我有一个如下形状的类型 foo, type foo = shape( ?'bar' => float, ... ); 现在,如果我尝试通过以下方式访问字段 bar 的值, do_
Hack 手册非常清楚如何对函数参数、函数返回类型和成员变量进行类型注释。但是,我尝试对全局变量或函数局部变量进行类型注释的所有方法都会导致语法错误: string $foo = "foo";
试图解决 HH 提示......基本上代码正在做类似的事情 Sfirstgroup = idx($largegroup, "first"); $final_thing = null if(HH\is_
有没有办法在严格的 Hack 模式下创建命令行程序?由于 Hack 的严格模式不允许函数外的语句,我不能调用我的 main功能。 (这是一个理论上的问题,因为通过使用非严格文件来调用 main 函数很
你好, 我有问题。我想在 hacklang 中模拟一些错误。 { return $this->vector; } public function test(Vector
我正在将 PHP 项目转换为 Hack 项目,但遇到了一些障碍。我想做的是将 IoC 容器从 PHP 重写为 Hack,但在让所有内容通过 Hack 类型检查器工具时遇到了一些麻烦。 所以基本上我拥有
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭去年。 Improve th
当尝试使用 hacklang/hhvm(今天编译)通过 PDO 访问 MySql 时,我收到一个 pdo 异常“找不到驱动程序”。我尝试安装 php5-mysql,但我什至不确定这是否有用,因为我不确
我目前无法构建 hhvm,因为无法访问 64 位 VM,所以我无法使用他们拥有的类型检查器。他们的文档似乎没有详细描述类型检查器(hh_server 和 hh_client?)的操作。 我想知道的是,
我是一名优秀的程序员,十分优秀!