# abstract struct Struct

- Struct
- Value
- Object

##
Overview

`Struct` is the base type of structs you create in your program. It is set as a struct's superstruct when you don't specify one:

    struct Foo # < Struct
    end

Structs inherit from `Value` so they are allocated on the stack and passed by value. For this reason you should prefer using structs for immutable data types and/or stateless wrappers of other types.

Mutable structs are still allowed, but code involving them must remember that passing a struct to a method actually passes a copy to it, so the method should return the modified struct:

    struct Mutable
      property value

      def initialize(@value : Int32)
      end
    end

    def change_bad(mutable)
      mutable.value = 2
    end

    def change_good(mutable)
      mutable.value = 2
      mutable
    end

    mut = Mutable.new 1
    change_bad(mut)
    mut.value # => 1

    mut = change_good(mut)
    mut.value # => 2

The standard library provides a useful `record` macro that allows you to create immutable structs with some fields, similar to a `Tuple` but using names instead of indices.

##
Direct Known Subclasses

- Atomic(T)
- Atomic::Flag
- BitArray
- Char::Reader
- Colorize::Color256
- Colorize::ColorRGB
- Colorize::Object(T)
- Complex
- Crystal::EventLoop::Polling::Arena::Entry(T)
- Crystal::EventLoop::Polling::Arena::Index
- Crystal::EventLoop::Polling::Event
- Crystal::EventLoop::Polling::PollDescriptor
- Crystal::EventLoop::Polling::Waiters
- Crystal::EventLoop::Timers(T)
- CSV::Builder::Row
- CSV::Row
- CSV::Token
- Enumerable::Chunk::Alone
- Enumerable::Chunk::Drop
- File::BraceStack(T)
- File::Info
- GC::ProfStats
- GC::Stats
- HTTP::FormData::FileMetadata
- HTTP::FormData::Part
- HTTP::Headers
- HTTP::StaticFileHandler::DirectoryListing
- IO::EncodingOptions
- JSON::Any
- JSON::Builder::ArrayState
- JSON::Builder::DocumentEndState
- JSON::Builder::DocumentStartState
- JSON::Builder::ObjectState
- JSON::Builder::StartState
- LLVM::ABI::ArgType
- LLVM::BasicBlock
- LLVM::BasicBlockCollection
- LLVM::DIBuilder
- LLVM::Function
- LLVM::FunctionCollection
- LLVM::FunctionPassManager::Runner
- LLVM::GlobalCollection
- LLVM::InstructionCollection
- LLVM::Metadata
- LLVM::OperandBundleDef
- LLVM::ParameterCollection
- LLVM::PassRegistry
- LLVM::PhiTable
- LLVM::Target
- LLVM::TargetData
- LLVM::Type
- LLVM::Value
- Log::Context
- Log::Emitter
- Log::Entry
- Log::Metadata::Value
- Log::StaticFormatter
- MIME::MediaType
- NoReturn
- Path
- Pointer::Appender(T)
- Process::Tms
- Range(B, E)
- Regex::MatchData
- SemanticVersion
- SemanticVersion::Prerelease
- Set(T)
- Slice(T)
- Socket::Address
- Socket::Addrinfo
- Spec::Example::Procsy
- Spec::ExampleGroup::Procsy
- Spec::SplitFilter
- String::Grapheme
- Time
- Time::Format
- Time::Instant
- Time::Location::Zone
- Time::MonthSpan
- Time::Span
- URI::Params
- UUID
- VaList
- Void
- XML::NodeSet
- YAML::Any

##
Defined in:

primitives.cr
struct.cr
yaml/any.cr

##
Class Method Summary

- .pre_initialize(address : Pointer) : Nil

  Performs basic initialization so that the given address is ready for use as an object's instance data.

  EXPERIMENTAL This API is still under development. Join the discussion about custom reference allocation at #13481.

##
Instance Method Summary

- #==(other : YAML::Any)
- #==(other) : Bool

  Returns `true` if this struct is equal to other.

- #hash(hasher)

  See `Object#hash(hasher)`

- #inspect(io : IO) : Nil

  Appends this struct's name and instance variables names and values to the given IO.

- #pretty_print(pp) : Nil
- #to_s(io : IO) : Nil

  Same as `#inspect(io)`.

### Instance methods inherited from struct `Value`

==(other : Log::Metadata::Value)
==(other : JSON::Any)
==(other : YAML::Any)
==(other) ==, dup dup

### Instance methods inherited from class `Object`

! : Bool !, !=(other) !=, !~(other) !~, ==(other) ==, ===(other : JSON::Any)
===(other : YAML::Any)
===(other) ===, =~(other) =~, as(type : Class) as, as?(type : Class) as?, class class, dup dup, hash(hasher)
hash hash, in?(collection : Object) : Bool
in?(*values : Object) : Bool in?, inspect(io : IO) : Nil
inspect : String inspect, is_a?(type : Class) : Bool is_a?, itself itself, nil? : Bool nil?, not_nil!(message)
not_nil! not_nil!, pretty_inspect(width = 79, newline = "\n", indent = 0) : String pretty_inspect, pretty_print(pp : PrettyPrint) : Nil pretty_print, responds_to?(name : Symbol) : Bool responds_to?, tap(&) tap, to_json(io : IO) : Nil
to_json : String to_json, to_pretty_json(indent : String = " ") : String
to_pretty_json(io : IO, indent : String = " ") : Nil to_pretty_json, to_s(io : IO) : Nil
to_s : String to_s, to_yaml(io : IO) : Nil
to_yaml : String to_yaml, try(&) try, unsafe_as(type : T.class) forall T unsafe_as

### Class methods inherited from class `Object`

from_json(string_or_io : String | IO, root : String)
from_json(string_or_io : String | IO) from_json, from_yaml(string_or_io : String | IO) from_yaml

### Macros inherited from class `Object`

class_getter(*names, &block) class_getter, class_getter!(*names) class_getter!, class_getter?(*names, &block) class_getter?, class_property(*names, &block) class_property, class_property!(*names) class_property!, class_property?(*names, &block) class_property?, class_setter(*names) class_setter, def_clone def_clone, def_equals(*fields) def_equals, def_equals_and_hash(*fields) def_equals_and_hash, def_hash(*fields) def_hash, delegate(*methods, to object) delegate, forward_missing_to(delegate) forward_missing_to, getter(*names, &block) getter, getter!(*names) getter!, getter?(*names, &block) getter?, property(*names, &block) property, property!(*names) property!, property?(*names, &block) property?, setter(*names) setter

##
Class Method Detail

def self.pre_initialize(address : Pointer) : Nil #

Performs basic initialization so that the given address is ready for use as an object's instance data.

More specifically, this is the part of object initialization that occurs after memory allocation and before calling one of the `#initialize` overloads. It zeroes the memory, and then runs all inline instance variable initializers.

address must point to a buffer of at least `sizeof(self)` bytes with an alignment of `alignof(self)` or above. This can for example be a pointer to an uninitialized instance.

This method only works for non-virtual constructions. Neither the struct type nor address's pointee type can be an abstract struct.

    struct Foo
      getter i : Int64
      getter str = "abc"

      def initialize(@i)
      end
    end

    foo = uninitialized Foo
    pointerof(foo).to_slice(1).to_unsafe_bytes.fill(0xFF)
    Foo.pre_initialize(pointerof(foo))
    foo # => Foo(@i=0, @str="abc")

See also: `Reference.pre_initialize`.

EXPERIMENTAL This API is still under development. Join the discussion about custom reference allocation at #13481.

##
Instance Method Detail

def ==(other : YAML::Any) #
def ==(other) : Bool #

Returns `true` if this struct is equal to other.

Both structs' instance vars are compared to each other. Thus, two structs are considered equal if each of their instance variables are equal. Subclasses should override this method to provide specific equality semantics.

    struct Point
      def initialize(@x : Int32, @y : Int32)
      end
    end

    p1 = Point.new 1, 2
    p2 = Point.new 1, 2
    p3 = Point.new 3, 4

    p1 == p2 # => true
    p1 == p3 # => false

def hash(hasher) #

See `Object#hash(hasher)`

def inspect(io : IO) : Nil #

Appends this struct's name and instance variables names and values to the given IO.

    struct Point
      def initialize(@x : Int32, @y : Int32)
      end
    end

    p1 = Point.new 1, 2
    p1.to_s    # "Point(@x=1, @y=2)"
    p1.inspect # "Point(@x=1, @y=2)"

def pretty_print(pp) : Nil #
def to_s(io : IO) : Nil #

Same as `#inspect(io)`.