运算符

This article describes Zephir’s operators. For precedence, you can check the Operator Precedence article.

Zephir’s operators are similar to the ones in PHP, and inherit some of their behaviors.

算术运算符

支持一下操作符

操作 示例
求反 -a
a + b
相减 a - b
a * b
a / b
取模 a % b

按位运算符

支持一下操作符

操作 示例
a & b
或(包括) a | b
Xor (exclusive or) a ^ b
~a
左移 a << b
右移 a >> b

示例︰

if a & SOME_FLAG {
    echo "has some flag";
}

Learn more about comparison of dynamic variables in the php manual.

比较运算符

比较运算符取决于比较变量的类型。 例如,如果两个比较操作数都是动态变量,其行为与PHP相同:

示例 操作 说明
a == b 等于 true如果a在去除类型后等于b。
a === b 完全相同的 true如果a等于b,它们是相同类型的。
a != b 不等于 true如果a在去除类型后不等于b。
a <> b 不等于 true如果a在去除类型后不等于b。
a !== b 不一致 true如果a不等于b,或者它们不是同一类型。
a < b 小于 如果a严格小于b,则true
a > b 大于 如果a严格大于b,则true
a <= b 小于或等于 true如果a小于或等于b。
a >= b 大于或等于 true如果a大于或等于b。

示例︰

if a == b {
    return 0;
} else {
    if a < b {
        return -1;
    } else {
        return 1;
    }
}

逻辑运算符

支持一下操作符

操作 示例
a && b
a || b
!a

示例︰

if a && b || !c {
    return -1;
}
return 1;

三元运算符

Zephir支持C或PHP中的三元运算符:

let b = a == 1 ? “x”:“y”; //如果a = 1, // b设为“x”,否则赋值为“y”

特殊运算符

支持一下操作符

Empty

这个运算符允许检查表达式是否为空。 ‘Empty’表示表达式为null,可以是空字符串或空数组:

let someVar = "";
if empty someVar {
    echo "is empty!";
}

let someVar = "hello";
if !empty someVar {
    echo "is not empty!";
}

Fetch

Fetch操作符将PHP中的一个常见操作简化为一条指令:

<?php

if (isset($myArray[$key])) {
    $value = $myArray[$key];
    echo $value;
}

在Zephir中,您可以编写与以下代码相同的代码:

if fetch value, myArray[key] {
    echo value;
}

‘Fetch’只返回true,只有在’key’是数组中的有效项的情况下进行’value’填充。

Isset

这个操作符检查是否在数组或对象中定义了属性或索引:

let someArray = ["a": 1, "b": 2, "c": 3];
if isset someArray["b"] { // check if the array has an index "b"
    echo "yes, it has an index 'b'\n";
}

使用isset作为返回表达式:

return isset this->{someProperty};

Note that isset in Zephir works more like PHP’s function array_key_exists, isset in Zephir returns true even if the array index or property is null.

Typeof

这个操作符检查变量的类型。 ‘typeof’可与比较运算符一起使用:

if (typeof str == "string") { // or !=
    echo str;
}

它也可以像PHP函数gettype那样工作。

return typeof str;

Be careful, if you want to check whether an object is ‘callable’, you always have to use typeof as a comparison operator, not a function.

类型提示

Zephir总是试图检查一个对象是否实现了方法和属性,这些方法和属性在一个被推断为对象的变量上被调用/访问:

let o = new MyObject();

// Zephir checks if "myMethod" is implemented on MyObject
o->myMethod();

但是,由于继承自PHP的动态性,有时很难知道对象的类,所以Zephir无法有效地生成错误报告。 类型提示告诉编译器哪个类与动态变量相关,允许编译器执行更多的编译检查:

// Tell the compiler that "o"
// is an instance of class MyClass
let o = <MyClass> this->_myObject;
o->myMethod();

这些 “类型提示” 很弱。 这意味着程序不检查该值是否实际上是指定类的实例, 也不检查它是否实现了指定的接口。 如果希望它每次执行时都检查此问题, 请使用严格的类型:

// 始终检查属性是否为实例
// 在使用前检查
let o = <MyClass!> this->_myObject;
o->myMethod();

分支预测提示

什么是分支预测? Check this article or refer to the Wikipedia article. 在性能非常重要的环境中, 引入这些提示可能会很有用。

请考虑下面的示例:

let allPaths = [];
for path in this->_paths {
    if path->isAllowed() == false {
        throw new App\Exception("Some error message here");
    } else {
        let allPaths[] = path;
    }
}

上述代码的作者事先知道, 引发异常的条件不太可能发生。 这意味着, 99.9% 的时间, 我们的方法执行该条件, 但它可能永远不会被评估为 true。 对于处理器, 这可能很难知道, 因此我们可以在那里引入一个提示:

let allPaths = [];
for path in this->_paths {
    if unlikely path->isAllowed() == false {
        throw new App\Exception("Some error message here");
    } else {
        let allPaths[] = path;
    }
}