当前位置: 首页 > 面试题库 >

语言构造和PHP中的“内置”函数有什么区别?

夹谷琨
2023-03-14
问题内容

我知道includeissetrequireprintecho,和其他一些人都没有的功能,但语言结构。

这些语言构造中的一些需要括号,而其他则不需要。

require 'file.php';
isset($x);

有些具有返回值,有些则没有。

print 'foo'; //1
echo  'foo'; //no return value

那么语言构造和内置函数之间的 内部 区别是什么?


问题答案:

(这比我打算的要长;请耐心等待。)

大多数语言由一种称为“语法”的东西组成:该语言由几个定义明确的关键字组成,并且您可以用该语言构造的完整表达范围都是由该语法建立的。

例如,假设您有一个简单的四功能算术“语言”,它仅将一位整数作为输入,而完全忽略了运算顺序(我告诉过您这是一种简单的语言)。该语言可以通过以下语法定义:

// The | means "or" and the := represents definition
$expression := $number | $expression $operator $expression
$number := 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
$operator := + | - | * | /

根据这三个规则,您可以构建任意数量的一位数字输入算术表达式。然后,您可以编写一个解析器这句法,打破了任何有效的投入到它的组件类型($expression$number$operator)并处理结果。例如,3 + 4 * 5可以将表达式分解如下:

// Parentheses used for ease of explanation; they have no true syntactical meaning
$expression = 3 + 4 * 5
            = $expression $operator (4 * 5) // Expand into $exp $op $exp
            = $number $operator $expression // Rewrite: $exp -> $num
            = $number $operator $expression $operator $expression // Expand again
            = $number $operator $number $operator $number // Rewrite again

现在,我们可以使用定义的语言对原始表达式进行完全解析的语法。一旦有了这个,我们就可以编写一个解析器来查找的所有组合的结果$number $operator $number,并在只剩下一个时吐出一个结果$number

请注意,$expression原始表达式的最终解析版本中没有剩余的构造。这是因为$expression在我们的语言中,总可以归结为其他事物的组合。

PHP大致相同:语言构造被认为与我们的$numberor 等效$operator。它们 不能简化为其他语言结构 ;
相反,它们是构建语言的基础单元。函数和语言构造之间的主要区别在于:解析器直接处理语言构造。它将功能简化为语言结构。

语言构造可能需要或可能不需要括号的原因,以及某些具有返回值而另一些却没有返回值的原因完全取决于PHP解析器实现的特定技术细节。我对解析器的工作原理不甚了解,因此我无法具体解决这些问题,但请想象一下以此开头的语言:

$expression := ($expression) | ...

实际上,该语言可以自由地使用它找到的任何表达式并摆脱周围的括号。PHP(这里我使用纯粹的猜测方法)对其语言结构可能采用类似的方式:print("Hello")可能会简化为print "Hello"解析之前的语言,反之亦然(语言定义既可以添加括号也可以删除括号)。

这就是为什么您不能重新定义诸如echo或的语言构造的根源print:它们已经有效地硬编码到了解析器中,而函数却映射到了一组语言构造,并且解析器允许您在编译时或运行时将其映射更改为替换您自己的一组语言构造或表达式。

归根结底,构造和表达式之间的内部差异是:解析器可以理解和处理语言构造。内置函数由语言提供,但在解析之前会映射并简化为一组语言结构。

更多信息:

  • Backus-Naur形式,用于定义形式语言的语法(yacc使用此形式)

编辑: 通读一些其他答案,人们会指出自己的观点。其中:

  • 内置的语言比函数调用起来更快。这是正确的,即使只是微不足道的,因为PHP解释器在解析之前不需要将该函数映射到其语言内置的等效项。但是,在现代机器上,差异几乎可以忽略不计。
  • 内置语言绕过错误检查。这可能是正确的,也可能不是正确的,具体取决于每个内置的PHP内部实现。的确,很多时候函数会具有更高级的错误检查以及内建函数没有的其他功能,这是事实。
  • 语言构造不能用作函数回调。的确如此,因为构造 不是函数 。他们是独立的实体。当您对内置函数进行编码时,您并不是在对带有参数的函数进行编码-内置函数的语法直接由解析器处理,并且被识别为内置函数,而不是函数。(如果您考虑使用具有一流功能的语言,这可能会更容易理解:有效地,您可以将功能作为对象传递。您不能使用内置函数来实现。)


 类似资料:
  • 我已经开始学习科特林了。我想知道 块和之间的区别。这与我们如何使用它来改进有什么区别?

  • 问题内容: 在C ++中,从构造函数内部调用虚拟函数时,它的行为不像虚拟函数。 我认为第一次遇到这种行为的每个人都会感到惊讶,但第二次认为这是有道理的: 只要派生的构造函数没有被执行的对象是 不是 又一个 衍生 实例。 那么如何调用派生函数呢?前提条件还没有建立的机会。例: Java和.NET完全相同,但是他们选择了另一种方式,这可能是 产生最少惊讶原则 的唯一原因吗? 您认为哪个是正确的选择?

  • 本文向大家介绍class和普通构造函数有什么区别?相关面试题,主要包含被问及class和普通构造函数有什么区别?时的应答技巧和注意事项,需要的朋友参考一下 构造函数可以当作普通的函数调用,而class 只能使用new 关键字调用 class 内部默认启用严格模式 class 不存在变量提示(函数提交)在定义class前使用new调用会出错 class 内部定义的方法和属性都是不可以遍历的。 cla

  • 主要内容:多种方式创建和初始化结构体——模拟构造函数重载,带有父子关系的结构体的构造和初始化——模拟父级构造调用Go语言的类型或结构体没有构造函数的功能,但是我们可以使用结构体初始化的过程来模拟实现构造函数。 其他编程语言构造函数的一些常见功能及特性如下: 每个类可以添加构造函数,多个构造函数使用函数重载实现。 构造函数一般与类名同名,且没有返回值。 构造函数有一个静态构造函数,一般用这个特性来调用父类的构造函数。 对于 C++ 来说,还有默认构造函数、拷贝构造函数等。 多种方式创建和初始化结构

  • 本文向大家介绍JavaScript中的匿名函数和内联函数有什么区别?,包括了JavaScript中的匿名函数和内联函数有什么区别?的使用技巧和注意事项,需要的朋友参考一下 匿名函数 顾名思义,匿名允许创建没有任何名称标识符的函数。它可以用作其他函数的参数。这就是可以使用JavaScript匿名函数的方式- 另一个示例可以如下- 内联函数 一个内联 函数是一个javascript函数,其被分配给在运

  • 实际上,我不明白无参数构造函数和默认构造函数的区别是什么。 在创建名为cFrame的Test对象时,是否调用此类的默认构造函数?