命名空间操作符...有什么了不起的?

13
有人能向我解释一下使用反斜杠作为命名空间运算符到底有什么问题吗?我读到了很多嘲笑的评论。甚至有一个 StackOverflower 说因为这个放弃了 PHP。
是的,我知道反斜杠在字符串内部具有转义字符的特殊含义,但它并不比在许多其他语言中使用箭头 "->" 或点 "." 更糟糕。
这有点让我想起了任天堂宣布 Wii 名称时所有的嘲笑。每个人都大惊小怪,然后一旦习惯了,就没人关心了,他们继续前进。
那么,请启迪我。它有什么问题?你会建议使用什么代替?
7个回答

12

为什么这样不好:你能在下面的代码中发现错误吗?

if(class_exists("namespace1\namespace2\myClass"))
    echo "This will never be true";

我会建议什么:不幸的是,'\'是唯一可用的单个字符。如果PHP6由我设计,我会用关键字代替所有的位运算符(^,&,|,~),并使用“|”作为命名空间分隔符(因为它们很少被使用)。实际上,我会建议更多简单的语法改变来使PHP更易于阅读和编写,但最好还是使用Python代替...


3
我发现在德国键盘上输入“\”键不太方便。而且,据我所知,没有其他语言使用反斜杠作为命名空间分隔符,这又导致了用稍微不同的方式做同一件事情的情况。 - stefs
1
Toby,因为这样每个 . 的实例都需要转义。 - jeffcook2150
5
你能不能使用单引号,这样PHP就不会解析字符串字面量中的任何文本? - alex
1
许多其他编程语言使用点字符作为命名空间分隔符,尽管它也是它们的主要面向对象分隔符 - 换句话说,在不同的上下文中,它具有不同的含义。PHP6为什么不能使用->或.并检查上下文呢? - user32826
2
你不能使用点号,因为在这样的语句中:MyNameSpace.MyClass,它会寻找两个名为"MyNameSpace"和"MyClass"的常量来进行字符串拼接(可能会导致一些警告,然后得到"MyNameSpaceMyClass")。同样地,如果你有一个同名的类和命名空间,箭头符号->也会导致歧义。 - nickf
显示剩余3条评论

3
此外,如果我想要一种没有特别好的理由重新发明语法的语言,我会使用Ruby。

它并不是在重新发明任何东西,只是使用了与其他语言不同的字符。 - nickf
3
真的吗?我最近查看PHP,它看起来非常类似于C++。这就是我选择它的原因,这是一种在不显着调整我的期望的情况下转移编程知识的好方法。在这个问题上,这是一个糟糕的决定,但它是可以应对的。但是没有任何人会询问任何数量的PHP用户后得出''符号符合用户需求的结论。实际上,这完全与用户预期不一致,这就是人们生气的原因。这个决定似乎没有反映出来自PHP程序员的任何输入。 - Jesse

3

它的问题在于几乎在任何其他上下文中都是转义字符。这意味着人们会无意中搞砸它,但也使得它难以阅读,因为你的眼睛已经调整为将反斜杠读作元字符,而不仅仅是另一个符号。

我更喜欢三个冒号,这实际上曾经被建议过。


“每个其他上下文”是指字符串和正则表达式吗?句号在作为运算符(字符串连接)、在正则表达式中(匹配任意字符)或在字符串中(表示句号)时有不同的含义。这似乎不会导致任何混淆,那么为什么 \ 会导致混淆呢? - nickf
我实际上是以更广泛的意义来说的。大多数编程语言都使用反斜杠作为转义字符。我认为 \ 与 a 不同,因为它增强了其后面的字符(至少在用于转义时是这样)。我同意 技术上 它并不是什么大问题,但我的眼睛已经习惯将特殊含义赋予该字符。 - troelskn

1

在使用反斜杠作为命名空间时,还存在其他问题。

  1. 反斜杠是转义字符。如果你必须在 "字符串" 中使用 \ 和在 '字符串' 中使用 \。我感觉某些人会在某个时候弄混它。迟早有一天,转义字符会让你出糗。
  2. 在每个键盘上, '\' 的位置都不太合适。在我的键盘上,我必须使用一些并不接近的键的组合,有时候这真的很痛苦。虽然它没有 '^' 那么糟糕。换句话说,无法流畅地编写需要访问某些按键映射上的命名空间的代码。
  3. 我记得他们投票决定了这个字符,结果非常荒谬。他们之所以选择它,是因为它比其他字符更简单,需要的输入量更少。说实话,这完全取决于你的键盘布局。

这就是我发现可能使用转义字符是一个坏事的所有原因了。 说实话,我还在等待一种能够创建自己的 Unicode 符号的语言出现。这样就可以在哪些操作符可以被覆盖方面提供更多的灵活性。就拿 C++ 来说,你可以这样写。

bool operator ≤ (Dog dog);
//and then do this
if(myDog ≤ thisDog){
}
//Seems useful?
bool operator ≅ thisDog){ 
  // this wouldn't check for equality 
  // but for something close to it
}

能够使用自己的任意运算符比使用+来分组更有意义..."∪"会更有意义...如果你想要获取交集,只需使用"∩",然后人们可能会说..."如果我们的字体中没有这些字符怎么办?"我只能回答:"找一个有它们的字体!!!"


虽然我同意在某些情况下 + 更有意义,但是如果没有字符面板或者大量的键盘组合等,输入这个字符并不容易。如果你想要形成两个集合的并集,打出 set1.union(set2); 可能比输入 更快,即使 (set1 ∪ set2) 看起来更漂亮。 - dreamlax

1

官方RFC和支持文件可以在以下链接找到:

它们包括有关决策过程的IRC日志

引用第"问题"部分

  • \ 看起来很像 /,对于 Unix 用户来说很容易不小心翻转。
  • \ 用于转义。
  • 在字符串中,命名空间名称变成 \\like\\this 或者我们可能会得到奇怪的字符。这可能会让用户感到困惑。
  • 所有现有的命名空间代码必须被重新编写,简单的搜索/替换 :: 是不可能的。
  • 该补丁涉及引擎的许多部分,需要进行严格的测试。
  • 对于许多人来说,\this\way 一开始看起来很奇怪。

你提到的任何嘲笑的言论都可能是由于上述原因或个人观点造成的。例如,我发现它们阅读起来很丑陋,写起来很麻烦,特别是在字符串中我必须使用双反斜杠。但是,随着我使用它们的次数越来越多,我会逐渐习惯它们。


0

假设以下命名空间:

jp\nintendo\rvl\testing

你注意到错误了吗?

实际(内部)命名空间很可能像这样:

jp
intendo
vl  esting

解决方法是始终使用两个反斜杠作为命名空间分隔符,类似于在Windows文件名中的使用方式。

使用两个反斜杠完全是无害的,因为它本身就是一个转义序列,它会扩展为一个单独的字面反斜杠,这是实际的命名空间分隔符。

现在,如果我们使用

jp\\nintendo\\rvl\\testing
作为命名空间(使用2个反斜线作为分隔符),实际(内部)命名空间变成:
jp\nintendo\rvl\testing


3
你的示例命名空间中没有错误。如果它在双引号字符串中,情况就会不同,但现在不是这种情况。 - nickf

0
真正的问题是,为什么他们不把它放在 / 上?我个人讨厌 \ ,因为它是一个转义字符……它会把一切都搞砸!

4
"/" 是除法运算符。"\" 怎么会把一切都搞砸呢? - nickf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接