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
Is There Any Way of Locking an Object in Swift Like in C#
Swift Error: Missing Argument Label 'Name:' in Call
Reversing the Order of a String Value
How to Detect a 'Click' Gesture in Swiftui Tvos
How to Get Date and Time to Show a Clock in Uilabel
Open a Viewcontroller from Remote Notification
Reading an Inputstream into a Data Object
Uitableview - Multiple Selection and Single Selection
Simple Clickable Link in Cocoa and Swift
Input Type=File Not Working in Webview of Os X Application
Calculate Area of Mkpolygon in an Mkmapview
Translucent Status Bar with No Navigation Bar
How to Connect Localhost (With Invalid Certificate) Using Alamofire
Subclass Nsapplication in Swift
Convert Bar Chart to a Grouped Bar Chart with Danielgindi/Ios-Charts and Swift