Ruby Cheat Sheet

我们可以通过 version manager 方便的切换多个版本。有时候你想要尝试新的功能,但又不想破坏当前项目。或者每个项目的版本又不一致,需要来回切换。
ruby

Ruby 的版本管理有rvmrbenv。现在主要的是用rbenv

brew install rbenv
rbenv versions
rbenv use 2.7.2
python

brew install pyenv
pyenv versions
pyenv global
pyenv local
javascript

yarn global add n
n
go

rust

ruby

Hash

{a: 1, b: 2, c: 3}
python

Dictionary

{'a': 1, 'b': 2, 'c': 3}

无论是字典dict还是集合set,背后都是散列表数据结构,结果就是占用内存很大,能够快速判断 key 是否存在。

javascript

// Object
{'a': 1, 'b': 2, 'c': 3}

// ES6 Map
const mapper = new Map([['1', 'a'], ['2', 'b']]);
go

// Map
ages := make(map[string]int) // 不能够初始化为nil,否则不能够赋值了
ages := map[string]int{
    "alice":   31,
    "charlie": 34,
}
rust

ruby

true
false
python

True
False
javascript

true;
false;
go

true
false
rust

true
false
ruby

arr = [1,2,3]
arr[1..]  # [2, 3]
arr[-1]   # [3]
arr[1..2] # [2, 3]
# 但是不支持 arr[::2]这样的操作

arr + [4, 5, 6] # [1,2,3,4,5,6]
python

arr = [1,2,3]
arr[1:]  # [2, 3]
arr[:2]  # [1, 2]
arr[::2] # [1, 3]
arr + [4, 5, 6] # [1,2,3,4,5,6]

for i in arr:
  print(i)

Python 里面还有一种数据类型叫元组。元组是不可变的,对应的就是列表是可变的。

python

此外,如果列表的元素都是数字,可以用array.array更为高效。

from array import array
from random import random
floats = array('d', (random() for i in range(10**7)))
fp = open('floats.bin', 'wb')
floats.tofile(fp)

array.array types

javascript

var arr = [1,2,3]
arr.slice(0, 2) // [1, 2]

[...arr, ...arr] // [1,2,3,1,2,3]
go

// Go语言里面很少使用数组,因为是固定长度的。
q := [...]int{1, 2, 3}
fmt.Printf("%T\n", q) // "[3]int"
fmt.Printf("%v\n", q) // "[1,2,3]"
// 相对应的是Slice,动态序列,和Python一样,支持各种切片操作
data := []string{"one", "", "three"}

fmt.Printf("%q\n", data)           // `["one" "three" "three"]`
fmt.Printf("%q\n", data[:2])      // `["one" ""]`

numbers := []int{1,2}
numbers = append(numbers, 3, 4)  // [1,2,3,4]
fmt.Printf("%v\n", numbers) // "[1,2,3,4]"
rust

// 切片
let s = String::from("hello world");

// 引用了s的一部分
let hello = &s[0..5];
let world = &s[6..11];

// 包括最后一个字符
let len = s.len();

let slice = &s[4..len];
let slice = &s[4..];

引用字符串的一部分

ruby

2.6.6 :027 > a = [1,2,3]
 => [1, 2, 3]
2.6.6 :028 > b = a
 => [1, 2, 3]
irb(main):011:0> a.object_id
=> 70076125215020
irb(main):012:0> b.object_id
=> 70076125215020
python

>>> a = [1,2,3]
>>> b = a
>>> id(b)
4315631168
>>> id(a)
4315631168
>>> a[2] = 4
>>> a
[1, 2, 4]
>>> b
[1, 2, 4]

# 一般不这样复制数组,而是通过一下方法
>>> a = [1,2,3]
>>> b = list(a)
>>> id(a)
4408133312
>>> id(b)
4408170944
javascript

go

a := []int{1,2,3}
b := a

fmt.Printf("%v\n", a)  // [1,2,3]
fmt.Printf("%v\n", b)  // [1,2,3]

a = append(a, 4)

fmt.Printf("%v\n", a)  // [1,2,3,4]
fmt.Printf("%v\n", b)  // [1,2,3]

// 这里需要注意的是,a和b共享了同一片内存空间,即[1,2,3]。
// 任何这里的修改都会互相影响。
rust

ruby

if true
    puts 'yes'
else
    puts 'no'
end
python

if True:
    print('yes')
elif False:
    print('no')
else:
    print('n/a')
javascript

if (true) {
  console.log("yes");
} else {
  console.log("no");
}
go

s := "bingo"

if s != "" {
  fmt.Println("yes")
} else {
  fmt.Println("no")
}
rust

ruby

(0..10).each do |i|
    puts i
end

{a: 1, b: 2}.each do |k, v|
    puts [k, v]
end
python

for i in [1,2,3]:
  print(i)

for i in range(10):
    print(i)

for i in count(start=0, step=1):
    print(i)

d = {'x': 1, 'y': 2, 'z': 3}
for k, v in d.items():
    print(k, v)

while True:
    quotient = num // output_base
    remainder = num % output_base

    output.append(remainder)
    num = quotient

    if quotient == 0:
        break
python

还可以通过推导式把列表转换成为字典

items = [
  ('apple', 10),
  ('orange', 5),
  ('banana', 7)
]

{item: price for item, price in items}

,或者集合。

from unicodedata import name
{ chr(i) for i in range(32, 256) if 'SIGN' in name(chr(i), '')}

javascript

let arr = ["a", "b", "c"];
for (let [k, v] of arr.entries()) {
  console.log(k);
  console.log(v);
}

let dict = { a: 1, b: 2, c: 3 };
for (let [k, v] of Object.entries(dict)) {
  console.log(k);
  console.log(v);
}
go

// Only for loop in Go

sum := 1
for sum < 100 {
  sum += 1
}
fmt.Println(sum)

// Infinite loop
// while true in Ruby

for {
  // do something
}

// each
kvs := map[string]string{"name": "Amy", "lastName": "Amy"}
for k, v := range kvs {
  fmt.Printf("%s -> %s\n", k, v)
}

// 如果是数组,第一个就是index
arr := []string{"a", "b", "c", "d", "e"}
for i, v := range arr {
  fmt.Println(i, v)
}
rust

ruby

# 在Ruby里面,函数和方法一般是同一个东西。
# 在英语里面,Function是独立的,可以调用的。Method是在类里面定义的函数,需要通过实例才可以调用它。

# 函数不是第一公民
# 这就意味着你不能够把函数赋值给变量,当作参数传入或者返回。
# 虽然可以通过symbol,或者lambda的方式来实现,但是总觉得是剑走偏锋了,一般都不这么用

python

# 函数是第一公民
# 在Python里面最典型的例子就是装饰器。装饰器其实就是把被修饰的函数B当做参数传入装饰器函数A,然后在返回一个新的函数C。
# 这样在执行函数B的时候,实际上是执行函数C,所以你可以在C里面定义额外的操作,比如给方法计时
# 你还可以嵌套多次装饰器,实现参数化的装饰器
javascript

// 一般没有提第一公民这事,但是的确存在
// 最显然的例子就是函数定义有两种方式,一种是函数声明,另外一种就是函数表达式
go

// 函数是第一公民
// 这就意味着函数可以当做值一样地处理
// 可以当作参数传入其他函数,也可以赋值给变量
// 甚至可以把一个实例的方法绑定给某个变量,调用这个变量其实就是调用这个实例的方法


p := Point{1, 2}
q := Point{4, 6}

distanceFromP := p.Distance        // method value
fmt.Println(distanceFromP(q))      // "5"

// 如果你是绑定struct里面的方法,那就需要第一个参数需要指定receiver
// 就像Python里面定义方法的时候,第一个参数是`self`或者`cls`

distance := Point.Distance   // method expression
fmt.Println(distance(p, q))  // "5"

rust

ruby

# 如果理解透,其实每个类是Class的一个实例

class A
end
a = A.new # <A:0x00007fb508870018>
a.class # A
A.class # Class

# 所以,所谓的类方法,实际上其实也是实例(Class的一个实例A)方法

# 定义类方法,有好几种方法
class A
  def self.m1
    puts 'm1'
  end

  class << self
    def m2
      puts 'm2'
    end
  end

end

A.instance_eval do
  def m3
    puts 'm3'
  end
end

module M4
  def m4
    puts 'm4'
  end
end

# A.extend M4

# 或者像下面那样,记住隐式的self
class A
  extend M4
end

# 调用的时候直接A.m1就行了
# 记住,A其实也是一个实例
python

from math import hypot

class Vector:
  def __init__(self, x = 0, y = 0):
    self.x = x
    self.y = y

  def __repr__(self):
    return 'Vector(%r, %r)' % (self.x, self.y)

  def __abs__(self):
    return hypot(self.x, self.y)

  def __bool__(self):
    return bool(abs(self))

  def __add__(self, other):
    return Vector(self.x + other.x, self.y + other.y)

  def __mul__(self, scalar):
    return Vector(self.x * scalar, self.y * scalar)
javascript

class Robot {
  name: string;
  static availableNames: string[];

  constructor() {
    this.name = Robot.generateName();
  }

  public resetName(): void {
    this.name = Robot.generateName();
  }

  public static releaseNames(): void {
    Robot.availableNames = [];
  }

  public static generateName(): string {
    if (
      Robot.availableNames === undefined ||
      Robot.availableNames.length === 0
    ) {
      Robot.availableNames = [];
      let letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
      let numbers = "0123456789".split("");
      for (const a of letters) {
        for (const b of letters) {
          for (const x of numbers) {
            for (const y of numbers) {
              for (const z of numbers) {
                Robot.availableNames.push([a, b, x, y, z].join(""));
              }
            }
          }
        }
      }
      // shuffle the array list
      for (let i = Robot.availableNames.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [Robot.availableNames[i], Robot.availableNames[j]] = [
          Robot.availableNames[j],
          Robot.availableNames[i],
        ];
      }
    }

    return Robot.availableNames.pop() as string;
  }
}
// https://googlechrome.github.io/samples/classes-es6/
go

rust

ruby

# method_missing
# define_method
# include / included
# prepend / prepended
# extend / extended

self.send(k)
python

getattr(self, k)()
javascript

go

rust

ruby

puts 's'
python

print('s')
javascript

console.log("s");
go

s := "s"
fmt.Println(s)
rust

ruby

irb(main):001:0> a = [3,2,1]
=> [3, 2, 1]
irb(main):002:0> a.sort
=> [1, 2, 3]
irb(main):003:0> a
=> [3, 2, 1]
python

a_list = [3,2,1]
a_list.sort() # None
a_list # [1,2,3]

如果你不想影响a_list,则可以用sorted方法。

a_list = [3,2,1]
sorted(a_list)
 # [1,2,3]
javascript

const arr = ["peach", "straw", "apple", "spork"];
arr.sort();

const arr = [5, 2, 3, 7, 9, 1];
arr.sort((a, b) => b - a);
go

import "sort"

strs := []string{"c", "a", "b"}
sort.Strings(strs)
fmt.Println("Strings:", strs)

ints := []int{7, 2, 4}
sort.Ints(ints)
fmt.Println("Ints:   ", ints)
rust

ruby

[['a', 7], ['b', 2]].sort_by { |k, v| v }  => [["b", 2], ["a", 7]]

# Ruby的类里面如果include了Enumerable并定义了<=>方法,那他们的实例就是可以比较的
# 具体的比较方法通过定义的<=>来实现的
# 比如下面的就是一个简单的二叉树节点的比较

class Bst

  include Enumerable

  attr_reader :left, :right, :data

  def initialize(new_data)
    @data = new_data
  end

  def insert(new_data)
    if new_data <= @data
      @left ? @left.insert(new_data) : @left = Bst.new(new_data)
    else
      @right ? @right.insert(new_data) : @right = Bst.new(new_data)
    end
    self
  end

  def each(&block)
    return to_enum unless block_given?

    @left&.each(&block)
    yield @data
    @right&.each(&block)

    self
  end

  def <=>(other)
    @data <=> other.data
  end

  def predecessor(key)
    self.each_cons(2).select { |e| e.last == key }.map(&:first)[0]
  end

  def successor(key)
    self.each_cons(2).select { |e| e.first == key }.map(&:last)[0]
  end

end
python

>>> a = [['a', 7], ['b', 2]]
>>> a.sort(key=lambda e: (e[1], e[0]), reverse=True)
>>> a
[['b', 2], ['a', 7]]

# Python 好像不屑于Ruby的spaceship operator
# 如果需要排序,用自定义排序就可以搞定了

javascript

// 如果记得Ruby中的宇宙飞船符的话,下面的通过函数自定义排序其实也是类似的
var items = [
  { name: "Edward", value: 21 },
  { name: "Sharpe", value: 37 },
  { name: "And", value: 45 },
  { name: "The", value: -12 },
  { name: "Magnetic", value: 13 },
  { name: "Zeros", value: 37 },
];

// sort by value
items.sort(function (a, b) {
  return a.value - b.value;
});

// sort by name
items.sort(function (a, b) {
  var nameA = a.name.toUpperCase(); // ignore upper and lowercase
  var nameB = b.name.toUpperCase(); // ignore upper and lowercase
  if (nameA < nameB) {
    return -1;
  }
  if (nameA > nameB) {
    return 1;
  }

  // names must be equal
  return 0;
});
go

// Need to implement sort.Interface - Len, Less, and Swap on type byLength

type byLength []string

func (s byLength) Len() int {
    return len(s)
}
func (s byLength) Swap(i, j int) {
    s[i], s[j] = s[j], s[i]
}
func (s byLength) Less(i, j int) bool {
    return len(s[i]) < len(s[j])
}

func main() {
    fruits := []string{"peach", "banana", "kiwi"}
    sort.Sort(byLength(fruits))
    fmt.Println(fruits)
}
rust

ruby

arr = []        # => []
arr.push(1)     # => [1]
arr.unshift(2)  # => [2, 1]
arr.shift       # => 2
arr.pop         # => 1
python

arr = []
arr.append(1)
arr.insert(0, 2) # => [2, 1]
arr.pop(0)      # => 2
arr.pop()       # => 1
javascript

var arr1 = [0, 1, 2];
arr1.push(3);
var arr2 = [4, 5, 6];
arr1.push(...arr2);
arr1.pop();
arr1.shift();
go

// go 没有pop方法,只能够自己写

func pop(alist *[]int) int {
   f:=len(*alist)
   rv:=(*alist)[f-1]
   *alist=append((*alist)[:f-1])
   return rv
}

func main() {
  n:=[]int{1,2,3,4,5}
  fmt.Println(n)
  last:=pop(&n)
  fmt.Println("last is",last)
  fmt.Printf("list of n is now %v\n", n)
}
rust

ruby

'13243432432'.scan(/\d/) => ["1", "3", "2", "4", "3", "4", "3", "2", "4", "3", "2"]

m = /\A(\d{3})(\d)/.match('13243432432') => #<MatchData "1324" 1:"132" 2:"4">
m[0] # "1324"
m[1] # "132"
python

import re
re.findall(r'\d', '1234232432')
# ['1', '2', '3', '4', '2', '3', '2', '4', '3', '2']

import re
s = 'a1b2c3'
s = 'a1b#2c3'
m = re.match(r'([^#]*)#(.*)', s)
m.group() # => 'a1b#2c3'
m.group(1) # => 'a1b'
m.group(2) # => '2c3'
javascript

const regex = /[a-zA-Z]/g;
const matched_chars = "abcdefg".match(regex);
// ['a', 'b', 'c', 'd', 'e', 'f', 'g']
go

rust

ruby

lst.find { |e| e == i }
python

next(x for x in seq if predicate(x))
javascript

const array1 = [5, 12, 8, 130, 44];
const found = array1.find((element) => element > 10);
// 12
go

rust

ruby

[1,2,3] + [4, 5, 6]
python

b = [1,2,3]
b.extend([5,4,6])
b + [7,8,9]
javascript

var a = [1, 2, 3];
// don't use + as it will return '1,2,34,5,6'
a.push(...[4, 5, 6]);
a; //[1,2,3,4,5,6]
go

rust

ruby

# 返回一个整数identifier,可以用来判断两个变量是否是同一个对象
a.object_id
python

id(a)
javascript

// no such method
go

rust

ruby

'str'.class
python

type('123')
'123'.__class__
javascript

Javascript详见继承关系

var a = "1,2,3";
a.__prop__.constructor;
go

rust

ruby

[1,1,1].uniq => [1]
python

list(set([1,1,1]))
javascript

let arr = [1,2,3,1,2,3]
[...new Set(arr)]
// [1, 2, 3]
go

rust

ruby

[1,2,3].map { |e| e * 3 }
python

一般建议用 Python 自带的列表推导,而不是用lambda,因为列表推导更加直观。

list(map(lambda x: x * 3, [1,2,3]))
[i * 3 for i in [1,2,3]]

上面的列表推导,还可以用元组来表示。两者的区别在于,列表推导是每个元素真实存在,而元组是迭代的时候才会生成下一个。所以,列表推导比较占内存,但是因为数据都在内存里面,所以速度比元组推导快。

javascript

[1, 2, 3, 4, 5].map((x) => x * 2);
go

rust

ruby

(-5..5).select { |x| x < 0 }
python

一般建议用 Python 自带的列表推导,而不是用lambda,因为列表推导更加直观。

less_than_zero = list(filter(lambda x: x < 0, range(-5, 5)))
[e for e in range(-5, 5) if e < 0]
javascript

Array.from({ length: 5 }, (v, i) => i).filter((x) => x % 2 === 0);
// [0, 2, 4]
ruby

[1,2,3].reduce(0) { |sum, x| sum + x }
[1,2,3].reduce(&:+)
python

from functools import reduce
reduce(lambda sum, x: sum + x, [1,2,3], 0)
javascript

const array1 = [1, 2, 3, 4];
array1.reduce((sum, x) => sum + x);
go

rust

ruby

[1,2,3].all { |e| e.even? }
python

all(len(g) % 2 == 0 for g in groups)
javascript

[2, 4, 6].every((x) => x % 2 === 0);
go

rust

ruby

[1,2,3].any? { |e| e > 1 } => true
python

any(x > 3 for x in [1,2,3]) # False
javascript

[2, 4, 6].some((x) => x % 2 === 0);
go

rust

ruby

a = {name: 'phx', age: 12}
a.merge({gender: 'male'})
python

In [51]: a = {'name': 'phx', 'age': 12 }

In [52]: a
Out[52]: {'name': 'phx', 'age': 12}

In [53]: a.update({'gender': 'male'})

In [54]: a
Out[54]: {'name': 'phx', 'age': 12, 'gender': 'male'}
javascript

var a = { a: 1 };
var b = Object.assign(a, { b: 2 });
// {a: 1, b: 2}
go

rust

ruby

[1,2,3,4,5,6,7,1,3].group_by {|e| e}.map { |k, v| [k, v.size]}.to_h
python

import collections
dict(collections.Counter([1,2,3,4,5,6,7,1,3]))
javascript

[1, 2, 3, 4, 5, 6, 7, 1, 3].reduce((acc, x) => {
  if (!acc[x]) acc[x] = 0;
  acc[x] += 1;
  return acc;
}, {});
go

rust

ruby

(1..5).to_a
python

list(range(10))
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
list(range(1, 10))
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
javascript

Array.from({ length: 5 }, (v, i) => i);
// [0, 1, 2, 3, 4]
go

rust

ruby

'foo'.chars
python

[char for char in 'foo']
javascript

Array.from("foo");
go

rust

"foo".chars()
ruby

begin
    1/0
rescue Exception => e
    p e
end
python

try:
    y = ALPHABET.index(char)
except ValueError:
    return char
javascript

go

rust

ruby

('a'..'z').to_a
python

from string import ascii_lowercase
ALPHABET = list(ascii_lowercase)
javascript

go

rust

ruby

[1,2,3].join('')
python

''.join([1,2,3])
javascript

[1, 2, 3].join("");
go

rust

ruby

7.to_s(2)
python

"{0:b}".format(7 % 256)
javascript

(10).toString(2);
go

rust

ruby

'101'.to_i(2)
python

int('101', 2)
javascript

parseInt("101", 2);
go

rust

ruby

"hello".tr('el', 'ip')      #=> "hippo"
"hello".tr('aeiou', '*')    #=> "h*ll*"
"hello".tr('aeiou', 'AA*')  #=> "hAll*"
python

ALPHABETS = list(chr(x) for x in range(ord('a'), ord('z')+1))
TRANSLATION_TABLE = str.maketrans(''.join(ALPHABETS), ''.join(reversed(ALPHABETS)))
[ch.translate(TRANSLATION_TABLE) for ch in 'aeiou']
javascript

go

rust

ruby

(1..3).to_a.permutation(2).to_a
 => [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]
python

>>> [i for i in itertools.permutations([1,2,3], 2)]
[(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
javascript

go

rust

ruby

a = [ 4, 5, 6 ]
b = [ 7, 8, 9 ]
[1, 2, 3].zip(a, b)   #=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
[1, 2].zip(a, b)      #=> [[1, 4, 7], [2, 5, 8]]
a.zip([1, 2], [8])    #=> [[4, 1, 8], [5, 2, nil], [6, nil, nil]]
python

name = [ "Manjeet", "Nikhil", "Shambhavi", "Astha" ]
roll_no = [ 4, 1, 3, 2 ]
marks = [ 40, 50, 60, 70 ]

# using zip() to map values
mapped = zip(name, roll_no, marks)

# converting values to print as set
mapped = set(mapped)

# printing resultant values
print ("The zipped result is : ",end="")
print (mapped)
# {('Nikhil', 1, 50), ('Astha', 2, 70), ('Manjeet', 4, 40), ('Shambhavi', 3, 60)}
javascript

go

rust

ruby

python

>>> mapped = {('Nikhil', 1, 50), ('Astha', 2, 70), ('Manjeet', 4, 40), ('Shambhavi', 3, 60)}
>>> namz, roll_noz, marksz = zip(*mapped)
>>> namz
('Manjeet', 'Astha', 'Shambhavi', 'Nikhil')
javascript

go

rust

ruby

sleep 1
python

import time
time.sleep(2)
javascript

function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

console.log("Hello");
sleep(2000).then(() => {
  console.log("World!");
});
go

rust

ruby

"%02d:%02d" % exact_time
format("%02d", 7) #有点不像ruby代码耶

a = 'hello'
"#{a} world"
python

'{:02d}:{:02d}'.format(7, 8)

'{:<30}'.format('left aligned')
# 'left aligned                  '
'{:>30}'.format('right aligned')
# '                 right aligned'
'{:^30}'.format('centered')
# '           centered           '
'{:*^30}'.format('centered')  # use '*' as a fill char
# '***********centered***********'

"int: {0:d};  hex: {0:x};  oct: {0:o};  bin: {0:b}".format(42)
# 'int: 42;  hex: 2a;  oct: 52;  bin: 101010'
# with 0x, 0o, or 0b as prefix:
"int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}".format(42)
# 'int: 42;  hex: 0x2a;  oct: 0o52;  bin: 0b101010'

'{:,}'.format(1234567890)
# '1,234,567,890'

points = 19
>>> total = 22
>>> 'Correct answers: {:.2%}'.format(points/total)
# 'Correct answers: 86.36%'
javascript

const a = "hello";
const b = `${a} world`;
console.log(b);
go

rust

ruby

python

javascript

go

rust

ruby

s = 'hello'
s.replace 'world' # => 'world'
python

'hello world'.replace('hello', 'world')
# 'world world'
javascript

const p =
  "The quick brown fox jumps over the lazy dog. If the dog reacted, was it really lazy?";

console.log(p.replace("dog", "monkey"));
// expected output: "The quick brown fox jumps over the lazy monkey. If the dog reacted, was it really lazy?"

const regex = /Dog/i;
console.log(p.replace(regex, "ferret"));
// expected output: "The quick brown fox jumps over the lazy ferret. If the dog reacted, was it really lazy?"
go

rust

python

import numpy
a = numpy.arange(12)
# array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

a.shape
# (12,)

a.shape = 3,4
# array([[ 0,  1,  2,  3],
#        [ 4,  5,  6,  7],
#        [ 8,  9, 10, 11]])

a[2]
# array([ 8,  9, 10, 11])

a[2, 1]
# 9

a[:, 1]
# array([1, 5, 9])

a.transpose()

# array([[ 0,  4,  8],
#        [ 1,  5,  9],
#        [ 2,  6, 10],
#        [ 3,  7, 11]])
bash

lsof -i -n -P | grep 3080
nc -zvt smtp.gmail.com 654
telnet smtp.gmail.com 654
ruby

require 'socket'

port_is_open = Socket.tcp(host, port, connect_timeout: 5) { true } rescue false

# non-blocking
require 'socket'
TIMEOUT = 2
def scan_port(port)
  socket      = Socket.new(:INET, :STREAM)
  remote_addr = Socket.sockaddr_in(port, 'www.example.com')
  begin
    socket.connect_nonblock(remote_addr)
  rescue Errno::EINPROGRESS
  end
  _, sockets, _ = IO.select(nil, [socket], nil, TIMEOUT)
  if sockets
    p "Port #{port} is open"
  else
    # Port is closed
  end
end

python

import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex(('127.0.0.1',80))
if result == 0:
   print "Port is open"
else:
   print "Port is not open"
sock.close()
javascript

go

rust

在 Rust 里面,字符串`String`是放在堆里面的,而字符串字面量是要编译进可执行文件的,会存放在栈里面的。
rust

字符串字面量是切片,但是切片的时候要小心,因为不一定刚好切在字符的后面。

let s: &str = "Hello, world!"; // 字符串切片
let s = String::from("hello,world!"); // 字符串

字符串无法索引,原因是s1实际上是字节数组,对于双字节的字符,拆开索引没有任何意义。

let s1 = String::from("hello");
let h = s1[0]; // 会报错
rust

Push

let mut s = String::from("Hello ");
s.push('r');
println!("追加字符 push() -> {}", s);

s.push_str("ust!");
println!("追加字符串 push_str() -> {}", s);

Insert

fn main() {
    let mut s = String::from("Hello rust!");
    s.insert(5, ',');
    println!("插入字符 insert() -> {}", s);
    s.insert_str(6, " I like");
    println!("插入字符串 insert_str() -> {}", s);
}

Replace

fn main() {
    let string_replace = String::from("I like rust. Learning rust is my favorite!");
    let new_string_replace = string_replace.replace("rust", "RUST");
    dbg!(new_string_replace);
}
rust

Pop

fn main() {
    let mut string_pop = String::from("rust pop 中文!");
    let p1 = string_pop.pop();
    let p2 = string_pop.pop();
    dbg!(p1);
    dbg!(p2);
    dbg!(string_pop);
}

Remove

fn main() {
    let mut string_remove = String::from("测试remove方法");
    println!(
        "string_remove 占 {} 个字节",
        std::mem::size_of_val(string_remove.as_str())
    );
    // 删除第一个汉字
    string_remove.remove(0);
    // 下面代码会发生错误
    // string_remove.remove(1);
    // 直接删除第二个汉字
    // string_remove.remove(3);
    dbg!(string_remove);
}

Truncate

fn main() {
    let mut string_truncate = String::from("测试truncate");
    string_truncate.truncate(3);
    dbg!(string_truncate); // 测
}

Clear

fn main() {
    let mut string_clear = String::from("string clear");
    string_clear.clear();
    dbg!(string_clear);
}

rust

Concatenate

++= 之后必须是 &str 类型。原因是背后实际调用的是add方法:fn add(self, s: &str) -> String

fn main() {
    let string_append = String::from("hello ");
    let string_rust = String::from("rust");
    // &string_rust会自动解引用为&str
    let result = string_append + &string_rust;
    let mut result = result + "!";
    result += "!!!";

    println!("连接字符串 + -> {}", result);
}


rust

Format

fn main() {
    let s1 = "hello";
    let s2 = String::from("rust");
    let s = format!("{} {}!", s1, s2);
    println!("{}", s);
}


#![allow(unused)]
fn main() {
    println!("Hello");                 // => "Hello"
    println!("Hello, {}!", "world");   // => "Hello, world!"
    println!("The number is {}", 1);   // => "The number is 1"
    println!("{:?}", (3, 4));          // => "(3, 4)"
    println!("{value}", value=4);      // => "4"
    println!("{} {}", 1, 2);           // => "1 2"
    println!("{:04}", 42);             // => "0042" with leading zeros
}
rust

转义

fn main() {
    println!("{}", "hello \\x52\\x75\\x73\\x74");
    let raw_str = r"Escapes don't work here: \x3F \u{211D}";
    println!("{}", raw_str);

    // 如果字符串包含双引号,可以在开头和结尾加 #
    let quotes = r#"And then I said: "There is no escape!""#;
    println!("{}", quotes);

    // 如果还是有歧义,可以继续增加,没有限制
    let longer_delimiter = r###"A string with "# in it. And even "##!"###;
    println!("{}", longer_delimiter);
}

ruby

python

javascript

go

rust

单引号只能够是字符,双引号是字符串

'中'
"中国人"
ruby

'abc'.bytes
python

javascript

go

rust

'abc'.bytes()
ruby

python

javascript

go

rust

浅拷贝只发生在栈上,因此性能很高。 任何基本类型的组合可以 Copy ,不需要分配内存或某种形式资源的类型是可以 Copy 的。

所有整数类型,比如 u32。
布尔类型,bool,它的值是 true 和 false。
所有浮点数类型,比如 f64。
字符类型,char。
元组,当且仅当其包含的类型也都是 Copy 的时候。比如,(i32, i32) 是 Copy 的,但 (i32, String) 就不是。
不可变引用 &T ,例如转移所有权中的最后一个例子,但是注意: 可变引用 &mut T 是不可以 Copy 的
rust

深拷贝 Rust 永远也不会自动创建数据的 “深拷贝”。除非显式的用clone()方法。

fn main() {
  let s1 = String::from("hello");
  let s2 = s1.clone();

  println!("s1 = {}, s2 = {}", s1, s2);
}

遇到一个问题,想在本地访问在 K8S 集群里面的内网地址,因为公网没法直接访问,需要把内网地址转发出来。解决方法是,在集群的 pod 内部用`socat`进行端口转发,再用`k port-forward`就可以将两者连起来。
bash

socat TCP-LISTEN:3309,fork,reuseaddr  TCP:mysql:3306