Ruby语言基础

ruby语言基础

1.ruby简介

编程界几大魔幻语言,c++JavaScriptrubyperl等,个个都是神奇而强大,好坏不一,魔幻的别称不是没来由。perl这辈子我是不会碰,c++JavaScript算是一家,学会了一种,另外一种过渡不算困难,c++是爱好。剩下就是ruby了,号称是要干死python,现在看来ruby其实已经半死不活。

本文就是针对ruby的,现学现卖,希望能够整理出一份比较容易入门的帖子。本文的角度是,假设已经掌握了一门语言,主要目的是快速掌握ruby的关键语言特性。因为你我的时间都很宝贵,不需要在语言语法上浪费过多的时间。

1.1.hello world

经典的例子,就是是hello world,ruby中一行语句就可以完成,和python类似。

# 这是一行,注释方法和python类似
puts 'hello world' # 括号可以省略

# p程序员专用 输出字符串时会带有引号,类似puts
p "hello world"

=begin
这是多行注释
puts有多个参数时,每个输出都会换行
print 只在最后添加换行
p 一般是给编程程序员使用
=end
print 'hello', 'world' # 等价于print('hello', 'world')
puts 'hello', 'world'

ruby中在<<之后,您可以指定一个字符串或标识符来终止字符串,且当前行之后直到终止符为止的所有行是字符串的值。

# 很ruby的用法,
print <

1.2.ruby之旅

1.2.1.顺序语句

定义变量的语法。

# 定义变量,和python一样
i = 1 # 整数
hi = 0xff # 16进制数
bi = 0b1011 # 二进制数

# 全局变量
$gi = 0
$gs = 'this is global string'

# 局部变量作用域,和python差不多
if true then
    if_local_var = 0
end
puts if_local_var # if语句内定义的变量依然可见

ruby语言是纯面向对象,连标准类型也是对象。

# 字符串
s = 'hello world' # 字符串
ss = "string value is #{i}" # 双引号可以通过变量格式化,有点类似python模板

# 下面字符串定义语法,很ruby
s = %q{hello world} # 同  s = 'hello world'
ss = %Q{string value is #{i}} # 同 ss = "string value is #{i}"
# 多行字符串定义
ss = %Q|first line
"second line"
|
puts ss # 输出多行 ,你可以使用{}、[]、||、<>、??、//、\\、;;等等都可以,不一定是{}

# 空值,nil不代表''
s = ''
if s == nil
    puts 's is null'
end

# 浮点数
f = 3.14
puts f.round # 3 四舍五入
puts f.ceil # 4 进位
puts f.to_i # 3 转换整数

其他语句的语法举例:

# 多重赋值
a, b, c = 1,2,3 # 定义变量a、b、c
a, b = b, a # 交换a和b的值
array = [1,3,4] # 定义数组
a, b, c = array # 数组解析到变量中

# 三元运算符?: 语句,和C++语法保持一致
max = (10 > 5) ? 10 : 5

# 常量,全部采用大写,如果改写会发出告警
PI = 3.14

# 基础的表达式 比如+ - * / % **
a = 1 * 2
a += 1 # 等价于a = a + 1

# 范围运算符
puts 1..3.to_a # [1, 2, 3]
puts 1...3.to_a # [1, 2]

# 数组与数组迭代
array = [1, 2, 3, 4]
array.each do |it|
    puts it
end
puts it # 注意,it生命周期已结束,it未定义

# 数组长度 length和size都是获取数组长度
nums = Array[1, 2, 3, 4,5]
puts "array size is: #{nums.length} or size: #{nums.size}"
puts "#{nums}"

# hash类型,类似json
hash = {"name" => 'ruby1', "age" => 20}
hash.each do | key, value |
    puts "key: #{key}, value: #{value}"
end
hash[:name] = 'ruby2' # 访问name节点,不能使用hash["name"]访问

1.2.2.条件语句

控制语句主要有条件、循环等,好消息ruby好像没有goto语句。

# 基本的条件语句:if 表达式用于条件执行。值 false 和 nil 为假,其他值都为真
i = 4
if i > 10 then
    puts 'i > 10'
elsif i > 5 then
    puts 'i > 5'
else
    puts 'i in else'
end

# if修饰符
puts 'pass' if 1 > 0
puts 'not ouput' if 0 > 0 # 条件不成立不会输出

# unless语句,与if相反,unless有存在的价值吗?
x = 1
unless x > 2
    puts "x <= 2"
else
    puts "x > 2"
end

# unlese修饰符
i = 0
puts 'get unless' unless i > 0

# case,这个确实有点丑
age =  5
case age
when 0 .. 2
    puts "baby"
when 3 .. 12
    puts "child"
when 13 .. 18
    puts "young"
else
    puts "adult"
end

# ruby没有with语句,可以自己定义一个

1.2.3.循环语句

循环语句主要有whiledountilforbreaknextredoretry等。

# while语句与while修饰符
a, b = 1, 10
while a < b do
    puts "a is #{a}"
    a += 1
end

a, b = 1, 10
begin
    puts "a is #{a}"
    a += 1 
end while a < b

# until语句
a, b = 1, 10
until a >= b do
    puts "a is #{a}"
    a += 1 
end

# until修饰符
a, b = 1, 10
begin
    puts "a is #{a}"
    a += 1 
end until a >= b

# for语句
for i in 0..10
    puts "i = #{i}"
end
puts i # i依然有定义,i = 10

#遍历数组
names = ['a', 'b']
for name in names
  p name
end

# each
(0..10).each do |ii|
    puts "ii = #{ii}"
end
puts ii # 此语句失败

# break
for i in 0..10
    if i > 3 then break end
    puts "i = #{i}"
end

# next if
for i in 0..10
    next if i < 3 # 如果i < 3就继续下次循环
    puts "i = #{i}"
end
# 等价于
for i in 0..10
    if i < 3 then next end
    puts "i = #{i}"
end

# redo语句
for i in 0..10
    if i < 3 then
        puts "i is #{i}"
        redo # 这里会出现死循环
    end
end

# retry语句已经废弃

# do语句
3.times do
    p 'times1'
end

# 用花括号代替 do end
3.times { p 'times2' }

3.times do |i|
    p "#{i + 1}times1"
end

3.times { |i|
    p "#{i + 1}times2"
}

name = ['a', 'b']
names.each do |name|
  p  name
end

1.2.3.异常语句

# 异常基本用法
begin
    p ii # ii未定义
rescue NameError
    # NameError是指定异常,如何不写,就是捕获所有异常
    p 'var ii is undefine'
ensure
    p 'must exec' # 无论是否有异常,一定会执行
end

# 主动抛出异常
raise Exception.new('this is exception')
raise RuntimeError.new('this is runtime exception')

# 异常隐藏问题,同大多数语言一致
begin
    p ii # ii未定义
rescue Exception => err
    p "you are here #{err}" # 会执行到这里
rescue NameError
   # 实际抛出NameError,被上面捕获拦截了,因为NameError是Exception的子类
    p 'var ii is undefine' 
end

1.2.3.函数

函数的基本定义:

# 定义一个方法
def first_method()
    puts 'this is first method'
end

# 带参数
def second_method(name, age=100)
    puts "name: #{name}, #{age}"
end
second_method('china')
second_method('earth',age=1000)
second_method(age=10000, name='sun') # 这里调用结果不是我们预期的,和python是有区别的
second_method(age:10000, name:'sun') # 这样调用也是不行的

# 括号可以省略
second_method 'china', 100
# 定义时候,也可以不用括号
def third_method name, age
    puts "name: #{name}, #{age}"
end
third_method 'sun', 10000

# 返回值 return
def return_one(a)
    return a * a
end
def return_two(a)
    return a * a, a ** 2
end
return_one(10)
a, b = return_two(10)

# 返回return,可以省略
def return_one(a)
    a * a # 这里省略了return,这很ruby
end
return_one(10)

函数的参数可变

# 可变参数函数
def sum(*element)
    ret = 0
    for i in 0...element.length
      ret += i
    end
    return ret
end
sum(1,2,3,4,5)

关键字参数,类似与python,不过python统一了关键字参数和非关键字参数用法。

def distance(x:0, y:0, z:0)
    return x**2 + y **2 + z **2
end

puts distance(z:1, x:2, y:3)
puts distance(1,2,3) # 语法错误

# 可变关键字参数
def distance(x:0, y:0, z:0, **kwags)
    a1 = x**2 + y **2 + z **2
    for v in kwags.values
        a1 += v ** 2
    end
    return a1
end
puts distance(x:1,y:2,z:3,m:4,n:5)

# 关键字参数和非关键字参数可以混用
def distance(x, y, z, **kwags)
    a1 = x**2 + y **2 + z **2
    for v in kwags.values
        a1 += v ** 2
    end
    return a1
end
puts distance(1,2,3,m:4,n:5)
puts distance(1,2,3,**{m:4,n:5})

函数的别名,取消函数定义、嵌套函数。

# 方法别名alias
alias mysum sum
mysum(1,2,3,4,5) # 调用新的别名方法

# 去除方法定义, 再调用sum和mysum都会出现方法未定义
undef mysum
# 嵌套函数
def outer_func()
    def inner_func()
        puts 'this is inner function'
    end

    inner_func()
    puts 'this is outer function'
end
outer_func()
inner_func() # 这里也可以调用内部函数
outer_func.inner_func() # 调用失败

# 取消定义
undef outer_func
inner_func() # 这里依然可以调用

lambda函数定义

# lambda函数
ff = lambda{|a,b| return a * b}
ff.call(10,20) # 这里ff调用需要加上.call

ruby由于函数参数都是动态类型,所以也就没有了函数重载能力。这一点和python比较类似。另外,ruby语言层面没有支持装饰器。

1.2.3.类

用户可以通过类创建自定义类型,关键字class和大多数语言一样的。我们定义一个类Student,有两个属性name和age,代码如下:

class Student
    # attr_accessor标示读写,只读attr_reader、只写attr_writer
    attr_accessor :name
    attr_accessor :age

    # 构造函数 initialize,接受两个参数
    def initialize(name, age)
        # 实例变量亿@开头
        @name=name
        @age=age
    end
end

s = Student.new('ssss', 100)
puts s.name
s.name = 'ssss2'
puts s.name
s.age = 200
puts s.age

类型定义,共有,私有和保护方法

class MyClass
    def private_method()
        puts 'private method'
    end

    def protected_method()
        puts 'protected method'
    end

    def public_method()
        puts 'public method'
    end

    private :private_method
    protected :protected_method
end

mc = MyClass.new()
mc.public_method()

# run error
mc.protected_method()
mc.private_method()

类定义静态属性,需要定义相应的方法,外部才能够访问。默认情况下,静态属性是私有的。

class StaticClass
    @@s_int = 0
    @@s_str = 'hello'

    def s_int
        @@s_int
    end

    def s_str
        @@s_str
    end

    def self.s_str
        @@s_str
    end

    # 定义类方法
    def StaticClass.static_method()
        puts 'this is static method'
    end
end

puts StaticClass.new.s_int
puts StaticClass.s_str
puts StaticClass.static_method()
# 静态方法,对象不能调用
puts StaticClass.new.static_method()

类继承

class Base
    def show
        puts 'show method from base'
    end

    def message
        puts 'message from base'
    end
end

class Child < Base
    def message
        puts 'message from child'
    end
end

base = Base.new
child = Child.new

base.message()
base.show()
child.message()
child.show()

# 关于多态,ruby是动态语言,天生就支持类型的多态

调用父类的构造方法

class Base1
    def initialize(name, age)
        puts "base init: #{name} #{age}"
    end
end

class Child1 < Base1
    def initialize(name, age, phone)
        super(name, age)
        puts "child init #{phone}"
    end
end

child = Child1.new('haha', 100, '136')

2.词法结构

3.基础类型

4.表达式

5.语句

6.字符串

7.数组

8.函数

9.类

10.模块

11.标准库

你可能感兴趣的:(Ruby语言基础)