Ruby与PHP:变量、常量、表达式和运算符的对比
在编程世界里,PHP和Ruby都是非常流行的语言。它们在变量、常量、表达式和运算符的使用上有很多不同之处。了解这些差异,能帮助开发者在不同场景下做出更合适的选择。
1. 类型转换
在类型转换方面,PHP和Ruby的处理方式截然不同。PHP会自动进行数据类型转换,而Ruby则需要开发者显式地进行转换。
PHP示例 :
print 1.4 + 4;
// => 5.4
print 1.1 + "2";
// => 3.1
print "3" + 5;
// => 8
Ruby示例 :
puts 1.4 + 4
# => 5.4
puts 1.1 + "2"
# => String can't be coerced into Float (TypeError)
puts 1.1 + "2".to_f
# => 3.1
puts "3" + 5
# => can't convert Fixnum into String (TypeError)
puts "3".to_i + 5
# => 8
从上述示例可以看出,在Ruby中,当需要将字符串转换为整数或浮点数时,必须使用
to_i
或
to_f
方法。
2. 变量
Ruby的变量有多种类型,包括局部变量、实例变量、类变量和全局变量,每种变量都有其特定的使用规则和作用域。
2.1 局部变量
Ruby的局部变量以小写字母或下划线开头,而PHP使用美元符号
$
来定义局部变量。在Ruby中,变量名和方法名可能会发生冲突,解决方法通常是重命名局部变量或在调用方法时使用括号。
PHP示例 :
$name = "Joe";
function name()
{
return "Jane";
}
print $name."\n";
// => "Joe"
print name()."\n";
// => "Jane"
Ruby示例 :
name = "Joe"
def name
"Jane"
end
puts name
# => "Joe"
puts name()
# => "Jane"
2.2 实例变量
实例变量以
@
符号开头,在同一个对象的所有方法中共享。
2.3 类变量
类变量以双
@
符号
@@
开头,类似于PHP中的静态类成员,在类的所有实例之间共享。
2.4 全局变量
Ruby的全局变量以美元符号
$
开头,与PHP不同的是,Ruby中使用美元符号的变量相当于PHP中的超全局变量,在任何地方都可以访问。不过,在实际编程中,应尽量避免使用全局变量,因为这可能会导致代码难以维护。
PHP示例 :
$name = 'Joe';
function foo()
{
global $name;
print $name;
}
foo();
// => Joe
Ruby示例 :
$name = 'Joe'
def foo
print $name
end
foo
# => Joe
2.5 变量作用域
Ruby和PHP的变量基本作用域非常相似。顶级作用域的变量可以在控制结构中使用,但不能在函数或方法中使用。函数和方法都有自己的局部作用域。
PHP示例 :
// local to the top-level
$a = 1;
if (true) {
$a = 2;
print $a; // => 2
}
print $a; // => 2
Ruby示例 :
# local to the top level scope
a = 1
if true
a = 2
puts a # => 2
end
puts a # => 2
3. 常量
在PHP中,常量只能存储标量数据,而在Ruby中,常量可以存储任何类型的数据,这使得Ruby的常量在更多场景下都能发挥作用。
PHP示例 :
define("MY_CONSTANT", "a");
print MY_CONSTANT; // => a
define("MY_CONSTANT", "b");
// PHP Notice: Constant MY_CONSTANT already defined
print MY_CONSTANT; // => a
Ruby示例 :
MY_CONSTANT = "a"
puts MY_CONSTANT # => a
MY_CONSTANT = "b"
# warning: already initialized constant MY_CONSTANT
puts MY_CONSTANT # => b
在Ruby中,任何以大写字母开头的名称都被视为常量,并且常量可以在运行时重新定义,但会抛出警告。
4. 表达式
Ruby的表达式与PHP类似,但有一些例外。Ruby的控制结构可以作为表达式进行求值并返回一个值,这有助于减少重复代码。
PHP示例 :
if ($day == 'saturday' || $day == 'sunday') {
$type = 'weekend';
} else {
$type = 'weekday';
}
Ruby示例 :
type = if day == 'saturday' || day == 'sunday'
'weekend'
else
'weekday'
end
5. 运算符
Ruby的运算符有很多独特之处,大多数运算符实际上是对象的方法调用。
5.1 赋值、算术和位运算
基本的算术、赋值和位运算符在PHP和Ruby中的使用几乎相同,但Ruby提供了额外的指数运算符
**
,相当于PHP的
pow()
函数。
PHP示例 :
list($a, $b, $c) = array(1, 2, 3);
print $a; # => 1
print $b; # => 2
print $c; # => 3
Ruby示例 :
a, b, c = 1, 2, 3
puts a # => 1
puts b # => 2
puts c # => 3
5.2 比较运算符
Ruby和PHP在比较运算符的使用上有一些差异。Ruby不支持
<>
运算符,并且在比较值时,Ruby是强类型的,而PHP是弱类型的。
PHP示例 :
var_export(1 == 1);
// => true
var_export(1 == 1.0);
// => true
var_export(1 == '1');
// => true
var_export(1 == true);
// => true
Ruby示例 :
puts 1 == 1
# => true
puts 1 == 1.0
# => true
puts 1 == '1'
# => false
puts 1 == true
# => false
5.3 其他运算符
在错误控制、执行、递增/递减、逻辑、字符串、数组和类型检查等方面,Ruby和PHP也有不同的处理方式。例如,Ruby没有PHP的前置和后置递增/递减运算符,而是使用修改后的赋值运算符来实现相同的功能。
综上所述,Ruby和PHP在变量、常量、表达式和运算符的使用上各有特点。开发者在选择使用哪种语言时,应根据具体的需求和场景来做出决策。同时,了解这些差异也有助于开发者在不同语言之间进行切换和学习。
下面是一个简单的流程图,展示了Ruby和PHP在变量类型上的差异:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
A([开始]):::startend --> B(变量类型):::process
B --> C(局部变量):::process
B --> D(实例变量):::process
B --> E(类变量):::process
B --> F(全局变量):::process
C --> C1(PHP: $开头):::process
C --> C2(Ruby: 小写或下划线开头):::process
D --> D1(PHP: 无特殊标识):::process
D --> D2(Ruby: @开头):::process
E --> E1(PHP: static关键字):::process
E --> E2(Ruby: @@开头):::process
F --> F1(PHP: 超全局变量):::process
F --> F2(Ruby: $开头):::process
C1 --> G([结束]):::startend
C2 --> G
D1 --> G
D2 --> G
E1 --> G
E2 --> G
F1 --> G
F2 --> G
通过这个流程图,我们可以更直观地看到Ruby和PHP在变量类型上的差异。希望这篇博客能帮助你更好地理解Ruby和PHP的相关知识。
Ruby与PHP:变量、常量、表达式和运算符的对比
6. 运算符详细对比
6.1 赋值、算术和位运算
| 类型 | PHP 示例 | Ruby 示例 |
|---|---|---|
| 基本算术运算 |
print 1 + 2; // => 3
|
puts 1.+(2); # => 3
|
| 并行变量赋值 |
list($a, $b, $c) = array(1, 2, 3);
|
a, b, c = 1, 2, 3
|
| 条件赋值 |
$result = isset($result) ? $result : 'foo';
|
result ||= 'foo'
|
在赋值、算术和位运算方面,虽然基本操作相似,但 Ruby 提供了更简洁的语法。例如并行变量赋值,Ruby 直接使用逗号分隔变量和值,而 PHP 需要使用
list
和
array
函数。条件赋值上,Ruby 的
||=
操作符是一种常用的简洁写法。
6.2 比较运算符
| 比较类型 | PHP 示例 | Ruby 示例 |
|---|---|---|
| 相等比较 |
var_export(1 == 1); // => true
var_export(1 == 1.0); // => true
var_export(1 == '1'); // => true
var_export(1 == true); // => true
|
puts 1 == 1; # => true
puts 1 == 1.0; # => true
puts 1 == '1'; # => false
puts 1 == true; # => false
|
| 相同类型和值比较 |
var_export(1 === 1); // => true
var_export(1 === 1.0); // => false
var_export(1 === '1'); // => false
var_export(1 === true); // => false
|
puts 1.eql?(1); # => true
puts 1.eql?(1.0); # => false
puts 1.eql?('1'); # => false
puts 1.eql?(true); # => false
|
| 对象 ID 比较 | 无 |
puts "a".equal?("a"); # => false
puts :a.equal?(:a); # => true
|
PHP 在相等比较时是弱类型的,会忽略变量类型,而 Ruby 是强类型的,不同类型的值即使看起来相等也会被判定为不相等。在相同类型和值比较上,Ruby 使用
eql?
方法,而 PHP 使用
===
运算符。对于对象 ID 比较,Ruby 提供了
equal?
方法,这在处理对象引用时非常有用。
6.3 错误控制
-
PHP
:使用
@符号来抑制错误,例如@define('MY_CONSTANT', 'b');。 -
Ruby
:最接近的做法是将
$VERBOSE级别设置为nil来抑制警告,Rails 还提供了silence_warnings方法。
# 使用 Ruby,我们可以更改详细级别以抑制警告
$VERBOSE = nil
MY_CONSTANT = 'b'
$VERBOSE = true
# Rails 提供了一个方便的方法,使用块来做同样的事情
silence_warnings do
MY_CONSTANT = 'c'
end
6.4 执行运算符
-
PHP
:使用反引号(
)来执行 shell 命令,例如printpwd;`。 -
Ruby
:既可以使用反引号,也可以使用
%x{}语法,例如putspwd;和puts %x{pwd};。
6.5 递增/递减运算符
-
PHP
:有前置和后置递增/递减运算符,例如
$a = 1; print ++$a; // => 2。 -
Ruby
:没有前置和后置递增/递减运算符,而是使用修改后的赋值运算符,例如
a = 1; puts a += 1; # => 2。
6.6 逻辑运算符
| 逻辑类型 | PHP 示例 | Ruby 示例 |
|---|---|---|
| 非运算 |
$result = !true; // $result == false
|
result = !true; # result == false
|
| 与运算 |
$result = 'test' && false; // $result == false
|
result = 'test' && false; # result == false
|
| 或运算 |
$result = 'test' || false; // $result == true
|
result = 'test' || false; # result == "test"
|
| 短路逻辑 |
$myVar = "test"; $myVar = $myVar || null; var_export($myVar); // => true
|
my_var = "test"; my_var = my_var || nil; puts my_var; # => "test"
|
Ruby 的
&&
和
||
运算符返回最后一个求值的值,而 PHP 返回布尔值,这在短路逻辑运算中会产生不同的结果。
6.7 字符串运算符
-
PHP
:使用点(.)进行字符串连接,例如
$a = "Chunky"; $b = $a . " Bacon!";。 -
Ruby
:使用加号(+)进行字符串连接,例如
a = "Chunky"; b = a + " Bacon!";。
6.8 数组运算符
| 操作类型 | PHP 示例 | Ruby 示例 |
|---|---|---|
| 数组联合 |
$fruit = array('apple') + array('kiwi', 'orange'); var_export($fruit); // => array(0 => 'apple', 1 => 'orange')
|
fruit = [:apple] + [:kiwi, :orange]; p fruit; # => [:apple, :kiwi, :orange]
|
| 数组比较 |
$result = array('a' => 1, 'b' => 2) == array('b' => 2, 'a' => 1); var_export($result); // => true
|
result = { :a => 1, :b => 2 } == { :b => 2, :a => 1 }; puts result; # => true
|
Ruby 数组的联合操作没有键冲突问题,因为 Ruby 数组没有键。在数组比较上,PHP 使用
==
进行相等比较,而 Ruby 也使用
==
,但在比较对象的同一性时,Ruby 使用
eql?
方法。
6.9 类型检查运算符
-
PHP
:使用
instanceof运算符来检查对象类型,例如if ($a instanceof MyClass) { print $a->myMethod(); }。 -
Ruby
:更倾向于使用
respond_to?方法来检查对象是否响应某个方法,而不是直接检查对象类型。
class MyClass
def my_method
'true'
end
end
class OtherClass; end
a = MyClass.new
b = OtherClass.new
if a.respond_to? :my_method
puts a.my_method # => true
end
7. 变量相关的其他特性
7.1 变量变量
- PHP :支持变量变量,但使用这种变量会导致代码难以理解,因此不建议使用。
- Ruby :不支持变量变量。
7.2
isset
/
empty
检查
| 语言 | 示例 | 说明 |
|---|---|---|
| PHP |
if (!isset($var1)) { print "var1 not set\n"; }
| 用于检查变量是否已赋值 |
| Ruby |
puts "var1 not set" unless var1; # => NameError: undefined local variable or method 'var1'
var2 = nil; puts "var2 not set" unless var2; # => var2 not set
|
访问未定义的局部变量会导致
NameError
,但可以访问未定义的实例变量,此时会返回
nil
|
Ruby 有
defined?
构造,类似于 PHP 的
isset
函数,但在正确定义变量时通常不需要使用。
8. 常量的特殊情况
8.1 魔法常量
| 常量 | PHP 示例 | Ruby 示例 |
|---|---|---|
__LINE__
|
print __LINE__; // => 2
|
puts __LINE__; # => 2
|
__FILE__
|
print __FILE__; // => /Users/derek/code/php_to_ruby_language/php/constants_magic.php
|
puts __FILE__; # => constants_magic.rb
puts File.expand_path(__FILE__); # => /Users/derek/code/php_to_ruby_language/ruby/constants_magic.rb
|
__CLASS__
|
class MyClass { public function myMethod() { print __CLASS__; // => MyClass } }
|
class MyClass; def my_method; puts self.class; # => MyClass; end; end
|
__FUNCTION__
|
function myFunction() { print __FUNCTION__; // => myFunction }
|
需要扩展
Object
类来实现类似功能
|
__METHOD__
|
class MyClass { public function myMethod() { print __METHOD__; // => MyClass::myMethod } }
|
需要扩展
Object
类来实现类似功能
|
Ruby 没有与 PHP 的
__FUNCTION__
、
__METHOD__
或
__CLASS__
常量完全等价的常量,但可以通过不同的方法来获取相同的信息。
下面是一个流程图,展示了 Ruby 和 PHP 在类型检查上的差异:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
A([开始]):::startend --> B(类型检查):::process
B --> C(PHP):::process
B --> D(Ruby):::process
C --> C1(instanceof 运算符):::process
C1 --> C2(检查对象是否属于某个类):::process
D --> D1(respond_to? 方法):::process
D1 --> D2(检查对象是否响应某个方法):::process
C2 --> E([结束]):::startend
D2 --> E
通过这个流程图,我们可以更清晰地看到 Ruby 和 PHP 在类型检查上的不同方式。总之,Ruby 和 PHP 在变量、常量、表达式和运算符等方面存在诸多差异。开发者在实际应用中,应根据项目的具体需求、团队的技术栈以及个人的编程习惯来选择合适的语言。同时,深入理解这些差异有助于在不同语言之间进行高效的开发和切换。
Ruby与PHP核心语法对比
超级会员免费看
6

被折叠的 条评论
为什么被折叠?



