Print Struct Name in Swift

Print Struct name in swift

If you need the name of the non instanciated struct you can ask for its self:

struct StructExample {
var variable1 = "one"
var variable2 = "2"
}

print(StructExample.self) // prints "StructExample"

For an instance I would use CustomStringConvertible and dynamicType:

struct StructExample: CustomStringConvertible {
var variable1 = "one"
var variable2 = "2"
var description: String {
return "\(self.dynamicType)"
}
}

print(StructExample()) // prints "StructExample"

Regarding Swift 3, self.dynamicType has been renamed to type(of: self) for the example here.

How do I correctly print a struct?

You’re initializing them just fine. The problem is your store struct is using the default printing, which is an ugly mangled version of the struct name.

If you make it conform to CustomStringConvertible, it should print out nicely:

// For Swift 1.2, use Printable rather than CustomStringConvertible 
extension Store: CustomStringConvertible {
var description: String {
// create and return a String that is how
// you’d like a Store to look when printed
return name
}
}

let me = Users(name: "Me", stores: [myFirstStore, mySecondStore])
println(me.stores) // prints "[H&M, D&G]"

If the printing code is quite complex, sometimes it’s nicer to implement Streamable instead:

extension Store: Streamable {
func writeTo<Target : OutputStreamType>(inout target: Target) {
print(name, &target)
}
}

p.s. convention is to have types like structs start with a capital letter

How to print output of method in a struct with Swift?

At the top level of a struct or class, you're only allowed to define functions and properties. For example, your let make:String = "MINI" or func getDetails() -> String { ... } are valid top-level declarations.

You are not, however, allowed to put imperative code that doesn't define a function or property (like print("")) at the top level of a type like this.

If you were in a Swift playground, you can put imperative code at the top level of the file (not of the struct or class). So, this would be valid:

struct Car {
let make:String = "MINI"
let model:String = "COOPER"
let year:String = "2015"

var details:String {
return year + " " + make + " " + model
}
func getDetails() -> String {
return details
}
}

let myCar = Car()
print(myCar.getDetails())

Since all getDetails does is return details, it's a bit superfluous, so we could refactor to just this:

struct Car {
let make:String = "MINI"
let model:String = "COOPER"
let year:String = "2015"

var details:String {
return year + " " + make + " " + model
}
}

let myCar = Car()
print(myCar.details)

What is the correct way to print address for generic struct Set, to understand the implication of copy-on-write behavior?

First, note that it is not the struct instances of Array<T> and Set<T> themselves that are copy-on-write. It is their backing stores that are. If you are confused by the fact that arrays and sets have backing stores, see this answer for a detailed description of how an array is structured. Sets are in a similar way.

Essentially, both Array and Set hold a reference to some reference type object (the backing store). If you look at the standard library source code, you can find __ContiguousArrayStorage and __RawSetStorage respectively, both of which are classes. It is this object that holds the actual elements in the collection, and it is this object that has COW behaviour. The Array and Set structs themselves behave like normal structs. After you do

var y = x

There are two Set structs in memory as you would expect, but they refer to the same backing store. withUnsafePointer gets the addresses of the two structs, which are of course different.

It's only when you modify one of them, that a new backing store object is created, and all the elements in the collection copied into the new backing store.

When you call print(address:) with an array, the array-to-pointer conversion actually gives you the pointer to the address of the backing store object, similar to how Array<T>.withUnsafeBufferPointer or Array<T>.withUnsafeBytes behave. Sets, on the other hand, don't have such a public API that gives you such a pointer.

You can use external tools to see the effect of COW though. A simple way is to use the Allocations instrument in Instruments.app to count how many set backing stores are allocated. Without any insert calls, there is only one allocation:

Sample Image

With one or two x.insert calls, there would be two allocations:

Sample Image

Structures: Swift Playground doesn't print username

I think I know what's happening here...

Let's break down what you've got in your code:

Everything between the outermost curly brackets here is associated with the User struct. You've set up all the properties correctly and the initialiser looks good. Ignore the logStatus() call in the initialiser for now.

Next, you have a 'logStatus' method declaration, which can apply to every instance of User that you create.

struct User {
let name: String
var email: String?
var followers: Int
let isActive: String

init(name: String, email: String?, followers: Int, isActive: String) {
self.name = name
self.email = email
self.followers = followers
self.isActive = isActive
logStatus()

}

func logStatus() {
print("\(userRichard.name) is \(isActive)")

}

}

So what's the problem?

I think the problem here is that you're calling the 'logStatus()' function inside the initialiser, before it has had chance to complete.

If you restructure your code as follows, it will work:

struct User {
let name: String
var email: String?
var followers: Int
let isActive: String

init(name: String, email: String?, followers: Int, isActive: String) {
self.name = name
self.email = email
self.followers = followers
self.isActive = isActive
}

func logStatus() {
print("\(name) is \(isActive)")
}

}

var userRichard = User(name: "Richard", email: "richard@icloud.com", followers: 0, isActive: "not active")
userRichard.logStatus()

I've stripped the 'userRichard' from the logStatus() function's .name bit. That means that if you call it on any instance of the User struct, it will show the corresponding name.

Next, I've called the function on the 'userRichard' instance of a User - after it has been initialised. The same approach should also work if you created a separate 'userPete' instance and so on.

Hopefully that makes sense.

How to print variables in structs in arrays?

Learn how to use map. I use it all the time.

print(contacts.map({ $0.name }))

Search for map in this Apple Documentation about Closures

How do I print certain elements of a struct in Swift?

There are many ways to do this.

You can use for loops:

// all makes
for car in Cars {
print(car.make)
}

// all models
for car in Cars {
for model in car.models {
print(model)
}
}

Or you can use higher-order functions like map and flatMap:

// all makes
print(Cars.map { $0.make })

// all models
print(Cars.flatMap { $0.models })


Related Topics



Leave a reply



Submit