This question already has answers here:
Is there difference between using a constructor and using .init?
(2 answers)
Closed 3 years ago.
Why we need to use init method explicitly while we can create an object without it
class Details {
}
var obj = Details()
var obj = Details.init()
What's the difference between these two instance creations
Both are allowed and are equivalent. As The Swift Programming Language says:
If you specify a type by name, you can access the type’s initializer without using an initializer expression. In all other cases, you must use an initializer expression.
let s1 = SomeType.init(data: 3) // Valid
let s2 = SomeType(data: 1) // Also valid
let s3 = type(of: someValue).init(data: 7) // Valid
let s4 = type(of: someValue)(data: 5) // Error
So, when you’re supplying the name of the type when instantiating it, you can either use the SomeType(data: 3) syntax or SomeType.init(data: 3). Most Swift developers would favor SomeType(data: 3) as we generally favor brevity unless the more verbose syntax lends greater clarity, which it doesn’t in this case. That having been said, SomeType.init(data: 3) is permitted, though it is less common in practice.
Class() is just a shorthand for Class.init()
Both are interpreted by the compiler as exactly the same statements with no difference at all.
Related
This question already has answers here:
Check if `Any` value is object
(2 answers)
Closed 3 years ago.
Is it possible to check if an object (not as in OOP) is of reference type or value type?
let something : Any = getSomething() // func getSomething() -> Any
let isReferenceType : Bool = // how to check?
EDIT:
As pointed out this is practically a duplicate of Check if `Any` value is object
This is not so easy as it seems, see
let isReferenceType: Bool = type(of: something) is AnyClass
See How to test whether generic variable is of type AnyObject
However, if you need such things, then usually you have some big problem with your architecture that you should address instead. Using Any type should be the last resort for exceptional situations.
Let's say I have a class:
class Fruit {
var fruitName: String
init(getFruit name: String) {
fruitName = name
}
}
Is there any difference between using the constructor, and using .init?
var apple = Fruit(getFruit: "apple")
var orange = Fruit.init(getFruit: "orange")
Im not seeing any difference in playground.
I apologize if the question is badly worded or has been asked before.
From the Initializer Expression section of the language guide:
If you specify a type by name, you can access the type’s initializer without using an initializer expression. In all other cases, you must use an initializer expression.
let s1 = SomeType.init(data: 3) // Valid
let s2 = SomeType(data: 1) // Also valid
let s3 = type(of: someValue).init(data: 7) // Valid
let s4 = type(of: someValue)(data: 5) // Error
Initializing using the explicit .init on the type directly is no different than without it; they are equivalent from Swift's perspective, so most folks prefer the brevity of omitting .init.
To my knowledge, there is absolutely no difference.
It is generally convention in Swift to call the constructor without the .init This is the 'swiftier' shorthand.
This question already has answers here:
In Swift, what's the difference between calling UINavigationController() vs UINavigationController.init()?
(3 answers)
Closed 5 years ago.
class A {
private var value: Int
init(value: Int) {
self.value = value
}
}
We have class A and what is the difference between I create this object by using A.init(value: 5) and A(value: 5)? Thanks
There is no functional difference between the two. Both styles will call the same initializer and produce the same value.
Most style guides that I've seen prefer to leave out the explicit .init-part in favor of the shorter A(value:) syntax — that also resembles the constructor syntax in many other languages.
That said, there are some scenarios where it's useful to be able to explicitly reference the initializer. For example:
when the type can be inferred and the act of initialization is more important than the type being initialized. Being able to call return .init(/* ... */) rather than return SomeComplicatedType(/* ... */) or let array: [SomeComplicatedType] = [.init(/* ... */), .init(/* ... */)]
when passing the initializer to a higher order function, being able to pass "something".map(String.init) rather than "something".map({ String($0) })
Again, it's a matter of style.
This question already has answers here:
When did `guard let foo = foo` become legal?
(1 answer)
Why isn't guard let foo = foo valid?
(1 answer)
Closed 5 years ago.
I'm reading from Erica Sadun's Swift Style book and playing around with some code.
She suggests:
Prefer using same-name shadowing in conditional bind. “This approach is both conventional and safe:
guard let x = x { ... } // yes
guard let y = x { ... } // no
Deliberate same-name shadowing ensures the the unwrapped value’s role follows the logical intent established by the name prior to the if or guard statement. Introducing a new name blurs the line of those semantics and can prove dangerous. Consistent same-named shadowing prevents you from adding an unintentional shadow to symbols in the parent scope.
Regardless of this being a good opinion or not:
In my code, I'm trying to do:
guard let data = data else{...}
but I get the following error:
Definition conflicts with previous value
A simplified version of my function is:
func process(){
data : AnyObject?
if x == nil{ data = m}
else if x > 5{ data = j}
guard let data = data else { return } // Definition conflicts with previous value
somefunc(data)
}
If I place the guard statement inside the if or else if then the error would go away. But that's not what I want.
Is there any workaround to still be able to do same-name shadow.
EDIT:
I tried using backticks and I get the following errors:
Expected Pattern
Braced block of statements is an unused closure
This question already has answers here:
println dictionary has "Optional"
(2 answers)
Closed 7 years ago.
If the following code runs
var airports = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
print(airports["YYZ"])
Why does the console print
Optional("Toronto Pearson")
Why does it print Optional( withValue ) and not just the value?
Why would I need to know that in the console?
Swift has optional types for operations that may fail. An array index like airports["XYZ"] is an example of this. It will fail if the index is not found. This is in lieu of a nil type or exception.
The simplest way to unwrap an optional type is to use an exclamation point, like so: airports["XYZ"]!. This will cause a panic if the value is nil.
Here's some further reading.
You can chain methods on option types in Swift, which will early exit to a nil without calling a method if the lefthand value is nil. It works when you insert a question mark between the value and method like this: airports["XYZ"]?.Method(). Because the value is nil, Method() is never called. This allows you to delay the decision about whether to deal with an optional type, and can clean up your code a bit.
To safely use an optional type without panicking, just provide an alternate path using an if statement.
if let x:String? = airports["XYZ"] {
println(x!)
} else {
println("airport not found")
}