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.
Related
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.
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.
This question already has an answer here:
Swift 3 incorrect string interpolation with implicitly unwrapped Optionals
(1 answer)
Closed 6 years ago.
I don't understand why the type system lets me do this?
In other words I would expect this to crash when foo is passed to the function.
var foo:String!
func someFunction(_ bar:String?) {
print("-- \(bar) --")
}
someFunction(foo)
=> writes "-- nil --"
As #Hamish so correctly points out here:
https://stackoverflow.com/a/39537558/308189
If the expression can be explicitly type checked with a strong optional type, it will be. However, the type checker will fall back to forcing the optional if necessary.
And the comment on the answer explains why this question was asked:
As if it weren't bad enough that you have to use an IUO, now they're less useful and behave contradictorily. If I use one it's because I want it to be implicitly unwrapped. They should be called Schrödinger Optionals from now on. – Andreas
Inside your someFunction you are printing the optional not String. that's why it is not crashing. if you want to print bar as String you have to unwrap the value.
// This line will create variable named foo and type of it will be String! and value of it will be nil.
// It mean i can access this variable is force-wraped so it may dangerous but uses of this variable without type checking compiler will not give any warning(ignore by compiler).
var foo:String!
// This function will accept `String` value or `nil`.
func someFunction(_ bar:String?) {
print("-- \(bar) --")
}
// So calling this function use of `foo`(valued nil) will not give any compiler issue.
someFunction(foo)
This question already has answers here:
When should I access properties with self in swift?
(6 answers)
Closed 7 years ago.
I have a trivial question.
Which do you use A or B in this case? Why?
obj and self.obj are exactly the same.
let obj = MyClass()
func sampleFunction(obj: MyClass) {
// A
obj.xxx()
// B
self.obj.xxxx()
}
self.obj refers to the instance of the class you are in and access the obj instance variable defined. Referring to obj will refer to the named parameter within the scope of the function.
class Test {
let obj = "Global"
func sampleFunction(obj: String) {
// A
print(obj)
// B
print(self.obj)
}
}
var t = Test()
t.sampleFunction("Internal")
Paste this into a Playground for a demo of this to aid the explanation.
It is subjective whether or not to use self to refer to instance variables, but if there is another local variable or named parameter with the same name as the instance variable in that scope - you must use self to differentiate like in the example.
It is a good rule-of-thumb to always use self to refer to instance variables, this improves readability and decreases the chance of bugs relating to conflicting local variable names in scope occurring.
This question already has answers here:
Stored type properties for classes in Swift
(2 answers)
Why no stored type properties for classes in swift?
(3 answers)
Closed 7 years ago.
I'm a Swift rookie and found myself confused when reading this paragraph from "The Swift Programming Language" reference book (on Language Guide > Properties > Type Properties):
“For value types (that is, structures and enumerations), you can define stored and computed type properties. For classes, you can define computed type properties only.”
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/br/jEUH0.l
But a couple of pages after this, the following code snippet can be found:
...
class SomeClass {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
// return an Int value here
}
class var overrideableComputedTypeProperty: Int {
// return an Int value here
}
}
...
Where a stored type property is clearly defined inside a class context, which apparently negates what was stated earlier.
So, is this a documentation error or am I just missing something?
Edit 1
I don't feel like this is a duplicate from this question. I'm not asking why this functionality is not implemented, because apparently it is currently implemented (since the compiler won't identify it as an error). All I'm asking is if the documentation os out of date or my interpretation is incorrect.
Edit 2
This issue was addressed here. Apparently the documentation is out of date. This functionality was added on Swift 1.2
I believe what the documentation meant (in a rather confusing way) is that you cannot have class stored vars (while you can still have static stored vars).
So, to summarize
class Foo {
static var bar: Int { // ok (computed static type variable)
return 2
}
static var foo = "" // ok (stored static type variable)
class var foobar: Int { // ok (computed class type variable)
return 2
}
class var baz = "" // nope (stored class type variable)
}