Does Swift Have an Implicit Object Initializer, Like in C#

Does Swift have an implicit Object Initializer, like in C#?

Not as such. If you create a custom struct, Swift will, under certain conditions, create a default memberwise initializer that is close to what you're looking for. But otherwise, I don't think there's even a way to implement such a feature, since Swift lacks anything like a with keyword that would get you into the new instance's scope.

Update: this is as close as I can get, by defining a custom operator:

infix operator <| { }

func <|<T>(decl: @autoclosure () -> T, f: T -> () ) -> T {
let obj = decl()
f(obj)
return obj
}

let label = UILabel() <| {
$0.frame = CGRect(x: 10, y: 10, width: 300, height: 25)
$0.text = "Hello"
$0.enabled = false
}

println(label)
// <UILabel: 0x7fb46240b210; frame = (10 10; 300 25); text = 'Hello'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fb46240c2b0>>

One-step object creation and property initialization in Swift?

You have a couple of options depending on how you want to configure this type and what syntax is most convenient for you.

You could define a convenient initializer which accepts the properties you want to set. Useful if you're setting the same properties all the time, less useful if you're setting an inconsistent set of optional properties.

public class Student
{
public var firstName:String?;
public var lastName:String?;
}

extension Student {
convenience init(firstName: String, lastName: String) {
self.init()
self.firstName = firstName
self.lastName = lastName
}
}

Student(firstName: "Any", lastName: "Body")

You could define a convenience initializer which accepts a block to configure the new instance.

extension Student {
convenience init(_ configure: (Student) -> Void ) {
self.init()
configure(self)
}
}

Student( { $0.firstName = "Any"; $0.lastName = "Body" } )

You could imitate Ruby's tap method as an extension so you can operate on an object in the middle of a method chain.

extension Student {
func tap(block: (Student) -> Void) -> Self {
block(self)
return self
}
}

Student().tap({ $0.firstName = "Any"; $0.lastName = "body"})

If that last one is useful you might want to be able to adopt tap on any object. I don't think you can do that automatically but you can define a default implementation to make it easier:

protocol Tap: AnyObject {}

extension Tap {
func tap(block: (Self) -> Void) -> Self {
block(self)
return self
}
}

extension Student: Tap {}

Student().tap({ $0.firstName = "Any"; $0.lastName = "body"})

c# object initialization - possible to reference properties by non-literal name?

You can use person.GetType().GetProperty(prop1).SetValue(person,"Joe"); Of course you need to add nullchecking on the GetProperty.

In Swift is it possible to create implicit conversions for your class types?

Swift doesn't support implicit conversion - the closest equivalent is done through extra constructors. So to convert a Double to an Int:

let i: Int = Int(myDouble)

In your case, you could define an extension to Int to create a new init that takes fauxInit as a parameter:

extension Int {
init(_ myFaux: FauxInt) {
self = myFaux.value
}
}

let fauxInt = FauxInt(14)
let realInt = Int(fauxInt)

Why create Implicitly Unwrapped Optionals, since that implies you know there's a value?

Consider the case of an object that may have nil properties while it's being constructed and configured, but is immutable and non-nil afterwards (NSImage is often treated this way, though in its case it's still useful to mutate sometimes). Implicitly unwrapped optionals would clean up its code a good deal, with relatively low loss of safety (as long as the one guarantee held, it would be safe).

(Edit) To be clear though: regular optionals are nearly always preferable.

Swift - Initialize class variables without constructor

Yes, for structs. No for classes.

Swift class introspection & generics

Well, for one, the Swift equivalent of [NSString class] is .self (see Metatype docs, though they're pretty thin).

In fact, NSString.class doesn't even work! You have to use NSString.self.

let s = NSString.self
var str = s()
str = "asdf"

Similarly, with a swift class I tried...

class MyClass {

}

let MyClassRef = MyClass.self

// ERROR :(
let my_obj = MyClassRef()

Hmm… the error says:

Playground execution failed: error: :16:1: error: constructing an object of class type 'X' with a metatype value requires an '@required' initializer

 Y().me()
^
<REPL>:3:7: note: selected implicit initializer with type '()'
class X {
^

It took me a while to figure out what this means… turns out it wants the class to have a @required init()

class X {
func me() {
println("asdf")
}

required init () {

}
}

let Y = X.self

// prints "asdf"
Y().me()

Some of the docs refer to this as .Type, but MyClass.Type gives me an error in the playground.

Why does captured object reference to implicitly unwrapped variable have to be unwrapped?

You can declare implicit unwrappedness, but you cannot propagate it. There is actually no such thing as an implicitly unwrapped Optional type, so when you pass or assign or capture a value declared as that type, it reverts to a normal Optional. For example:

 var forced: String! = "test"
let x = forced

You will find that x is an ordinary Optional, a String?. Your captured value is like that.



Related Topics



Leave a reply



Submit