ruby中如何向C++一样定义和使用多维数组

Python016

ruby中如何向C++一样定义和使用多维数组,第1张

C++中定义与使用数组跟C语言中是一样的。

具体定义与使用方法可以参考如下程序段:

int a[5] // 定义一个含5个元素的int类型的数组double b[5]={3.2, 3.5, 0.8, 8, 5,3} // 定义一个含5个元素的double类型的数组并初始化char c[] ="abcd" // 定义一个字符数组,并初始化a[0] = c[0] // 将字符数组的第一个字符所对应的ASCII码值赋值给数组a的第一个元素printf("%lf", b[3]) // 输出数组b的第4个元素(数组下标从0开始)

数组的创建和初始化

a = Array.[](1,2,3,4)

b = Array[1,2,3,4]

c = [1,2,3,4]

d = Array.new #创建一个空数组

e = Array.new(3) #[nil,nil,nil] 初始大小3

f = Array.new(3,"xx") #["xx","xx","xx"] 初始大小3 初始值"xx"

f[0].capitalize! #=>["Xx","Xx","Xx"]

g = Array.new(3){"yy"} #=>["yy","yy","yy"]

g[0].capitalize! #=>["Yy","yy","yy"]

有3种方式,

1. 使用send方法

第一种实现动态方法调用是使用send方法,send方法在Object类中定义,方法的第一个参数是一个符号用来表示所要调用的方法,后面则是所调用方法需要的参数。

“This is a dog1″.send(:length) =>14

上面的代码中通过send方法去对一个字符串执行length操作,返回字符串的长度。

class TestClass

def hello(*args)

”Hello ” + args.join(‘ ‘)

end

end

a = TestClass.new

puts a.send :hello, “This”, “is”, “a”, “dog!”

执行结果为:

Hello This is a dog!

2. 使用Method类和UnboundMethod类

另一种实现动态方法调用是使用Object类的method方法,这个方法返回一个Method类的对象。我们可以使用call方法来执行方法调用。

test1 = “This is a dog1″.method(:length)

test1.call =>14

class Test

def initialize(var)

@var = var

end

def hello()

”Hello, @var = #{@var}”

end

end

k = Test.new(10)

m = k.method(:hello)

m.call #=>“Hello, @iv = 99″

l = Test.new(‘Grant’)

m = l.method(“hello”)

m.call #=>“Hello, @iv = Fred”

可以在使用对象的任何地方使用method对象,当调用call方法时,参数所指明的方法会被执行,这种行为有些像C语言中的函数指针。你也可以把method对象作为一个迭代器使用。

def square(a)

a*a

end

mObj = method(:square)

[1, 2, 3, 4].collect(&mObj) => [1 4 9 16]

Method对象都是和某一特定对象绑定的,也就是说你需要通过某一对象使用Method对象。你也可以通过UnboundMethod类创建对象,然后再把它绑定到某个具体的对象中。如果UnboundMethod对象调用时尚未绑定,则会引发异常。

class Double

def get_value

2 * @side

end

def initialize(side)

@side = side

end

end

a = Double.instance_method(:get_value) #返回一个UnboundMethod对象

s = Double.new(50)

b = a.bind(s)

puts b.call

执行结果为:

100

看下面一个更具体的例子:

class CommandInterpreter

def do_2() print “This is 2\n”end

def do_1() print “This is 1\n”end

def do_4() print “This is 4\n”end

def do_3() print “This is 3\n”end

Dispatcher = {

?2 =>instance_method(:do_2),

?1 =>instance_method(:do_1),

?4 =>instance_method(:do_4),

?3 =>instance_method(:do_3)

}

def interpret(string)

string.each_byte {|i| Dispatcher[i].bind(self).call }

end

end

interpreter = CommandInterpreter.new

interpreter.interpret(’1234′)

执行结果为:

This is 1

This is 2

This is 3

This is 4

3. 使用eval方法

我们还可以使用eval方法实现方法动态调用。eval方法在Kernel模块中定义,有多种变体如class_eval,module_eval,instance_eval等。Eval方法将分析其后的字符串参数并把这个字符串参数作为Ruby代码执行。

str = “Hello”

eval “str + ‘ World!’” =>Hello World!

sentence = %q{“This is a test!”.length}

eval sentence =>15

当我们在使用eval方法时,我们可以通过eval方法的第二个参数指明eval所运行代码的上下文环境,这个参数可以是Binding类对象或Proc类对象。Binding类封装了代码在某一环境运行的上下文,可以供以后使用。

class BindingTest

def initialize(n)

@value = n

end

def getBinding

return binding() #使用Kernel#binding方法返回一个Binding对象

end

end

obj1 = BindingTest.new(10)

binding1 = obj1.getBinding

obj2 = BindingTest.new(“Binding Test”)

binding2 = obj2.getBinding

puts eval(“@value”, binding1) #=>10

puts eval(“@value”, binding2) #=>Binding Test

puts eval(“@value”) #=>nil

可以看到上述代码中,@value在binding1所指明的上下文环境中值为10,在binding2所指明的上下文环境中值为Binding Test。当eval方法不提供binding参数时,在当前上下文环境中@value并未定义,值为nil。