首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Struct

父类:ObjectIncluded模块:Enumerable

Struct是一种使用访问器方法将多个属性捆绑在一起的简便方法,无需编写显式类。

Struct类生成包含一组成员及其值的新子类。对于每个成员,创建一个类似于Module#attr_accessor的读写器方法。

代码语言:javascript
复制
Customer = Struct.new(:name, :address) do
  def greeting
    "Hello #{name}!"
  end
end

dave = Customer.new("Dave", "123 Main")
dave.name     #=> "Dave"
dave.greeting #=> "Hello Dave!"

有关创建结构子类和实例的更多示例,请参阅:: new。

在后面的方法描述中,“成员”参数指的是一个结构成员,它是一个带引号的字符串("name")或一个符号(:name)。

常量

组是一个Struct,只有在编译时才可用HAVE_GETGRENT

该结构包含以下成员:

名字

以String形式包含组的名称。

passwd

包含加密密码作为字符串。如果组的密码访问不可用,则返回'x'; 如果不需要密码来获取组的成员资格,则返回空字符串。

必须与编译HAVE_STRUCT_GROUP_GR_PASSWD

gid

包含组的数字ID作为整数。

mem

是包含组成员简短登录名的字符串数组。

Passwd

Passwd

Passwd是包含以下成员的Struct:

name

包含用户的短登录名作为字符串。

passwd

包含用户的加密密码作为字符串。如果正在使用阴影密码,则会返回'x'。如果用户无法使用密码登录,则会返回'*'。

uid

包含用户的整数用户ID(uid)。

gid

包含用户主组的整数组ID(gid)。

dir

以String形式包含用户主目录的路径。

shell

包含用户的登录shell的路径作为字符串。

以下成员是可选的,并且必须使用特殊标志进行编译:

gecos

包含用户的更长字符串描述,例如全名。一些Unix系统在gecos领域提供结构化信息,但这是依赖于系统的。必须与编译HAVE_STRUCT_PASSWD_PW_GECOS

change

密码更改时间(整数)必须使用编译 HAVE_STRUCT_PASSWD_PW_CHANGE

quota

配额值(整数)必须用。编译 HAVE_STRUCT_PASSWD_PW_QUOTA

age

密码的年龄(整数)必须用。编译 HAVE_STRUCT_PASSWD_PW_AGE

class

用户访问类(字符串)必须使用编译 HAVE_STRUCT_PASSWD_PW_CLASS

comment

评论(字符串)必须与编译 HAVE_STRUCT_PASSWD_PW_COMMENT

expire

帐户到期时间(整数)必须用。编译 HAVE_STRUCT_PASSWD_PW_EXPIRE

Tms

公共类方法

json_create(object) 显示源

通过构造具有v序列化值的新结构对象来反序列化JSON字符串to_json

代码语言:javascript
复制
# File ext/json/lib/json/add/struct.rb, line 10
def self.json_create(object)
  new(*object['v'])
end

new(class_name+) → StructClass 显示源

new(class_name+) {|StructClass| block } → StructClass

new(value, ...) → object

StructClassvalue, ... → object

前两个表单用于创建一个新的Struct子类class_name,其中可以包含每个值的值member_name。这个子类可以像任何其他类一样用于创建结构的实例。

如果class_name省略,则会创建一个匿名结构类。否则,此结构的名称将在类Struct中显示为常量,因此它必须对系统中的所有Structs都是唯一的,并且必须以大写字母开头。给一个常量赋一个结构类也给这个类定义了这个常量的名字。

代码语言:javascript
复制
# Create a structure with a name under Struct
Struct.new("Customer", :name, :address)
#=> Struct::Customer
Struct::Customer.new("Dave", "123 Main")
#=> #<struct Struct::Customer name="Dave", address="123 Main">

# Create a structure named by its constant
Customer = Struct.new(:name, :address)
#=> Customer
Customer.new("Dave", "123 Main")
#=> #<struct Customer name="Dave", address="123 Main">

如果给出了一个块,它将在上下文中进行评估StructClass,将创建的类作为参数传递:

代码语言:javascript
复制
Customer = Struct.new(:name, :address) do
  def greeting
    "Hello #{name}!"
  end
end
Customer.new("Dave", "123 Main").greeting  #=> "Hello Dave!"

这是定制结构的推荐方法。子类化匿名结构会创建一个永远不会被使用的额外的匿名类。

最后两个窗体创建一个结构子类的新实例。value参数的数量必须小于或等于为结构定义的属性的数量。取消设置参数默认为nil。传递比属性数量更多的参数会引发ArgumentError。

代码语言:javascript
复制
Customer = Struct.new(:name, :address)
Customer.new("Dave", "123 Main")
#=> #<struct Customer name="Dave", address="123 Main">
Customer["Dave"]
#=> #<struct Customer name="Dave", address=nil>
代码语言:javascript
复制
static VALUE
rb_struct_s_def(int argc, VALUE *argv, VALUE klass)
{
    VALUE name, rest;
    long i;
    VALUE st;
    st_table *tbl;

    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
    name = argv[0];
    if (SYMBOL_P(name)) {
        name = Qnil;
    }
    else {
        --argc;
        ++argv;
    }
    rest = rb_ident_hash_new();
    RBASIC_CLEAR_CLASS(rest);
    tbl = RHASH_TBL(rest);
    for (i=0; i<argc; i++) {
        VALUE mem = rb_to_symbol(argv[i]);
        if (st_insert(tbl, mem, Qtrue)) {
            rb_raise(rb_eArgError, "duplicate member: %"PRIsVALUE, mem);
        }
    }
    rest = rb_hash_keys(rest);
    st_clear(tbl);
    RBASIC_CLEAR_CLASS(rest);
    OBJ_FREEZE_RAW(rest);
    if (NIL_P(name)) {
        st = anonymous_struct(klass);
    }
    else {
        st = new_struct(name, klass);
    }
    setup_struct(st, rest);
    if (rb_block_given_p()) {
        rb_mod_module_eval(0, 0, st);
    }

    return st;
}

公共实例方法

struct == other→true或false显示源代码

Equality-Returns true如果other具有相同的结构子类并具有相同的成员值(根据Object#==)。

代码语言:javascript
复制
Customer = Struct.new(:name, :address, :zip)
joe   = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joejr = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
jane  = Customer.new("Jane Doe", "456 Elm, Anytown NC", 12345)
joe == joejr   #=> true
joe == jane    #=> false
代码语言:javascript
复制
static VALUE
rb_struct_equal(VALUE s, VALUE s2)
{
    if (s == s2) return Qtrue;
    if (!RB_TYPE_P(s2, T_STRUCT)) return Qfalse;
    if (rb_obj_class(s) != rb_obj_class(s2)) return Qfalse;
    if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
        rb_bug("inconsistent struct"); /* should never happen */
    }

    return rb_exec_recursive_paired(recursive_equal, s, s2, s2);
}

structmember → object 显示源

structindex → object

属性引用 - 返回给定结构的值member或给定的成员index。如果member不存在则引发NameError,如果index超出范围则引发IndexError 。

代码语言:javascript
复制
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)

joe["name"]   #=> "Joe Smith"
joe[:name]    #=> "Joe Smith"
joe[0]        #=> "Joe Smith"
代码语言:javascript
复制
VALUE
rb_struct_aref(VALUE s, VALUE idx)
{
    int i = rb_struct_pos(s, &idx);
    if (i < 0) invalid_struct_pos(s, idx);
    return RSTRUCT_GET(s, i);
}

structmember = obj → obj 显示源

structindex = obj → obj

属性分配 - 设置给定结构member或给定成员的值index。如果member不存在则引发NameError,如果index超出范围则引发IndexError 。

代码语言:javascript
复制
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)

joe["name"] = "Luke"
joe[:zip]   = "90210"

joe.name   #=> "Luke"
joe.zip    #=> "90210"
代码语言:javascript
复制
VALUE
rb_struct_aset(VALUE s, VALUE idx, VALUE val)
{
    int i = rb_struct_pos(s, &idx);
    if (i < 0) invalid_struct_pos(s, idx);
    rb_struct_modify(s);
    RSTRUCT_SET(s, i, val);
    return val;
}

as_json(*) 显示源

返回一个散列,它将变成一个JSON对象并表示这个对象。

代码语言:javascript
复制
# File ext/json/lib/json/add/struct.rb, line 16
def as_json(*)
  klass = self.class.name
  klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!"
  {
    JSON.create_id => klass,
    'v'            => values,
  }
end

dig(key, ...) → object 显示源

key通过dig在每个步骤调用来抽取由对象序列指定的嵌套值,nil如果有任何中间步骤则返回nil

代码语言:javascript
复制
Foo = Struct.new(:a)
f = Foo.new(Foo.new({b: [1, 2, 3]}))

f.dig(:a, :a, :b, 0)    # => 1
f.dig(:b, 0)            # => nil
f.dig(:a, :a, :b, :c)   # TypeError: no implicit conversion of Symbol into Integer
代码语言:javascript
复制
static VALUE
rb_struct_dig(int argc, VALUE *argv, VALUE self)
{
    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
    self = rb_struct_lookup(self, *argv);
    if (!--argc) return self;
    ++argv;
    return rb_obj_dig(argc, argv, self, Qnil);
}

each {|obj| block } → struct 显示源

each → enumerator

按顺序产生每个结构成员的值。如果没有给出块,则返回枚举器。

代码语言:javascript
复制
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.each {|x| puts(x) }

生产:

代码语言:javascript
复制
Joe Smith
123 Maple, Anytown NC
12345
代码语言:javascript
复制
static VALUE
rb_struct_each(VALUE s)
{
    long i;

    RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size);
    for (i=0; i<RSTRUCT_LEN(s); i++) {
        rb_yield(RSTRUCT_GET(s, i));
    }
    return s;
}

each_pair {|sym, obj| block } → struct 显示源

each_pair → enumerator

按顺序产生每个结构成员的名称和值。如果没有给出块,则返回枚举器。

代码语言:javascript
复制
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.each_pair {|name, value| puts("#{name} => #{value}") }

生产:

代码语言:javascript
复制
name => Joe Smith
address => 123 Maple, Anytown NC
zip => 12345
代码语言:javascript
复制
static VALUE
rb_struct_each_pair(VALUE s)
{
    VALUE members;
    long i;

    RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size);
    members = rb_struct_members(s);
    if (rb_block_arity() > 1) {
        for (i=0; i<RSTRUCT_LEN(s); i++) {
            VALUE key = rb_ary_entry(members, i);
            VALUE value = RSTRUCT_GET(s, i);
            rb_yield_values(2, key, value);
        }
    }
    else {
        for (i=0; i<RSTRUCT_LEN(s); i++) {
            VALUE key = rb_ary_entry(members, i);
            VALUE value = RSTRUCT_GET(s, i);
            rb_yield(rb_assoc_new(key, value));
        }
    }
    return s;
}

eql?(other) → true or false 显示源

散列相等 - 如果它们具有相同的结构子类并具有相同的成员值(根据Object#eql?)other,则struct引用相同的散列键。

代码语言:javascript
复制
static VALUE
rb_struct_eql(VALUE s, VALUE s2)
{
    if (s == s2) return Qtrue;
    if (!RB_TYPE_P(s2, T_STRUCT)) return Qfalse;
    if (rb_obj_class(s) != rb_obj_class(s2)) return Qfalse;
    if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
        rb_bug("inconsistent struct"); /* should never happen */
    }

    return rb_exec_recursive_paired(recursive_eql, s, s2, s2);
}

hash → integer 显示源

根据这个结构的内容返回一个散列值。

代码语言:javascript
复制
static VALUE
rb_struct_hash(VALUE s)
{
    long i, len;
    st_index_t h;
    VALUE n;
    const VALUE *ptr;

    h = rb_hash_start(rb_hash(rb_obj_class(s)));
    ptr = RSTRUCT_CONST_PTR(s);
    len = RSTRUCT_LEN(s);
    for (i = 0; i < len; i++) {
        n = rb_hash(ptr[i]);
        h = rb_hash_uint(h, NUM2LONG(n));
    }
    h = rb_hash_end(h);
    return INT2FIX(h);
}

to_s → string 显示源

inspect → string

以字符串形式返回此结构的描述。

代码语言:javascript
复制
static VALUE
rb_struct_inspect(VALUE s)
{
    return rb_exec_recursive(inspect_struct, s, 0);
}

另外别名为:to_s

length → integer 显示源

返回结构成员的数量。

代码语言:javascript
复制
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.length   #=> 3
代码语言:javascript
复制
VALUE
rb_struct_size(VALUE s)
{
    return LONG2FIX(RSTRUCT_LEN(s));
}

members → array 显示源

以符号数组形式返回结构成员:

代码语言:javascript
复制
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.members   #=> [:name, :address, :zip]
代码语言:javascript
复制
static VALUE
rb_struct_members_m(VALUE obj)
{
    return rb_struct_s_members_m(rb_obj_class(obj));
}

select {|obj| block } → array 显示源

select → enumerator

将每个成员值从结构体传递到块,并返回一个Array struct,其中包含给定块返回true值(等于Enumerable#select)的成员值。

代码语言:javascript
复制
Lots = Struct.new(:a, :b, :c, :d, :e, :f)
l = Lots.new(11, 22, 33, 44, 55, 66)
l.select {|v| v.even? }   #=> [22, 44, 66]
代码语言:javascript
复制
static VALUE
rb_struct_select(int argc, VALUE *argv, VALUE s)
{
    VALUE result;
    long i;

    rb_check_arity(argc, 0, 0);
    RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size);
    result = rb_ary_new();
    for (i = 0; i < RSTRUCT_LEN(s); i++) {
        if (RTEST(rb_yield(RSTRUCT_GET(s, i)))) {
            rb_ary_push(result, RSTRUCT_GET(s, i));
        }
    }

    return result;
}

size → integer 显示源

返回结构成员的数量。

代码语言:javascript
复制
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.length   #=> 3
代码语言:javascript
复制
VALUE
rb_struct_size(VALUE s)
{
    return LONG2FIX(RSTRUCT_LEN(s));
}

to_a → array 显示源

以数组形式返回此结构的值。

代码语言:javascript
复制
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.to_a[1]   #=> "123 Maple, Anytown NC"
代码语言:javascript
复制
static VALUE
rb_struct_to_a(VALUE s)
{
    return rb_ary_new4(RSTRUCT_LEN(s), RSTRUCT_CONST_PTR(s));
}

to_h → hash 显示源

返回包含结构成员的名称和值的哈希。

代码语言:javascript
复制
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.to_h[:address]   #=> "123 Maple, Anytown NC"
代码语言:javascript
复制
static VALUE
rb_struct_to_h(VALUE s)
{
    VALUE h = rb_hash_new();
    VALUE members = rb_struct_members(s);
    long i;

    for (i=0; i<RSTRUCT_LEN(s); i++) {
        rb_hash_aset(h, rb_ary_entry(members, i), RSTRUCT_GET(s, i));
    }
    return h;
}

to_json(*args) 显示源

将具有结构值的类名称(Struct)存储v为JSON字符串。仅支持命名的结构。

代码语言:javascript
复制
# File ext/json/lib/json/add/struct.rb, line 27
def to_json(*args)
  as_json.to_json(*args)
end

to_s()

别名为:检查

values → array 显示源

以数组形式返回此结构的值。

代码语言:javascript
复制
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.to_a[1]   #=> "123 Maple, Anytown NC"
代码语言:javascript
复制
static VALUE
rb_struct_to_a(VALUE s)
{
    return rb_ary_new4(RSTRUCT_LEN(s), RSTRUCT_CONST_PTR(s));
}

values_at(selector, ...) → array 显示源

将每个结构成员值selector作为数组返回。A selector可以是整数偏移量或偏移量范围(如在Array#values_at中)。

代码语言:javascript
复制
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.values_at(0, 2)   #=> ["Joe Smith", 12345]
代码语言:javascript
复制
static VALUE
rb_struct_values_at(int argc, VALUE *argv, VALUE s)
{
    return rb_get_values_at(s, RSTRUCT_LEN(s), argc, argv, struct_entry);
}

扫码关注腾讯云开发者

领取腾讯云代金券

http://www.vxiaotou.com