How to update a global variable in Swift by reference? - swift

My question is simple in the C language, just access the global variable using access with a pointer -
demoFunc(int *someVar) {
*someVar = 1234;
return;
}
How do you do this in Swift? For simplicity and clarity, how do you do this for the following code?
class Example {
var globalInt : Int = 0;
func someMain() {
self.modifyVar(?&globalInt?); //Q: How do you do this?
return;
}
func modifyVar(?&someVar?) { //Q: ?
someVar = 1234; //Q: ?
return;
}
}

This code:
var toto = 3
class Example {
var globalInt = 0
func someMain() {
self.modifyVar(&globalInt)
}
func modifyVar(inout someVar: Int) {
someVar = 1234
}
}
let vc = Example()
print(vc.globalInt)
vc.someMain()
print(vc.globalInt)
print(toto)
vc.modifyVar(&toto)
print(toto)
produces
0
1234
3
1234

Related

How we can change variable of protocol in Swift

I have two class that implemented from same protocol
protocol MyProtocol{
}
class MyFirstClass : MyProtocol{
var test : Int = 0
}
class MySecondClass : MyProtocol{
var test : Int = 0
}
How can I have a function that increase test variable each time I pass object of MyFirstClass or MySecondClass
something like this
var a = MyFirstClass()
var b = MySecondClass()
func inc(myObject : MyProtocol){
myObject.test ++ // myObject has no member `test`
}
inc(a)
inc(a)
inc(b)
inc(a)
This is the complete Swift 3 code:
protocol MyProtocol: class {
var test: Int { get set }
}
class MyFirstClass: MyProtocol {
var test: Int = 0
}
class MySecondClass: MyProtocol {
var test: Int = 0
}
func inc(_ obj: MyProtocol) {
obj.test += 1
}
var a = MyFirstClass()
var b = MySecondClass()
inc(a)
print(a.test) // 1
inc(a)
print(a.test) // 2
inc(b)
print(b.test) // 1
inc(a)
print(a.test) // 3
Important note:
I've made MyProtocol class only, as this allow code optimization.
If you want it to any type (not only classes), you can adopt #Hamish solution (you can read more about this in the comments below)

Swift return bool in method

I've made this method:
func checkScore(player: Int) -> Bool {
var checkedFields: [Int] = []
var won: Bool = false
for var i = 0; i <= 9; i += 1 {
if(winningCombinations[i] == player) {
checkedFields.append(i)
}
}
for value in winningCombinations {
var hits = 0
for n in checkedFields {
if value.contains(n){
hits += 1
}
}
if hits == 3 {
won = true
}
}
return won
}
But when I try to build it everything becomes white and the build crashes. Am I doing something wrong here? I pass the value like this:
if self.checkScore(player) {
print("Won!")
}
(I see no error message!)
Your func checkScore(player: Int) accepts player, which is of type Int.
In your code you also say : if(winningCombinations[i] == player), meaning that you expect the elements in array winningCombinations to also be of type Int
But then you say
for value in winningCombinations {
var hits = 0
for n in checkedFields {
if value.contains(n){
If value is an element in winningCombination, it means that value is an int.. how can you say value.contains(n). Int cannot perform contains operation. Arrays can.

Can you get __FUNCTION__ from the caller?

Example:
#noreturn func setOnlyPropertyGetterError(__function__: String) {
fatalError("\(__function__) is set-only")
}
var property: Property {
get {setOnlyPropertyGetterError(__FUNCTION__)}
set {//useful work}
}
Can we avoid having to pass __FUNCTION__?
I think this is what you want to achieve:
#noreturn func writeOnlyProperty(propertyName: String = __FUNCTION__) {
fatalError("Property \(propertyName) is write-only")
}
class Foo {
var blackHole: Int {
get { writeOnlyProperty() }
set { print("Consuming value \(newValue)") }
}
}
let foo = Foo()
foo.blackHole = 1 // Prints "Consuming value 1"
let bar = foo.blackHole // Produces fatal error "Property blackHole is write-only"

Subscript of a struct doesn't set values when created as an implicitly unwrapped optional

Why can't I change the the "numbers" array using subscripts when "Foo" is an implicitly unwrapped optional?
struct Foo {
var numbers = [0,0,0]
subscript(index: Int) -> Int {
get { return self.numbers[index] }
set { self.numbers[index] = newValue }
}
}
var fooA:Foo!
fooA = Foo()
fooA[1] = 1 // does not change numbers array
fooA[1] // returns 0
fooA.numbers[1] = 1 // this works
fooA[1] // returns 1
var fooB:Foo!
fooB = Foo()
fooB![1] = 1 // this works
fooB![1] // returns 1
For some reason it works when I make "Foo" a class (called "Goo" below)
class Goo {
var numbers = [0,0,0]
subscript(index: Int) -> Int {
get { return self.numbers[index] }
set { self.numbers[index] = newValue }
}
}
var goo:Goo!
goo = Goo()
goo[1] = 1 // this works
goo[1] // returns 1
it looks like a bug (or i miss something important), check this
struct Foo {
var numbers = [0,0,0]
subscript(index: Int) -> Int {
get {
return self.numbers[index]
}
set {
numbers[index] = newValue
}
}
}
var fooA:Foo! = Foo()
// here is the difference
fooA?[1] = 1
fooA[1] // 1
fooA.numbers[1] = 1
fooA[1] // 1
more 'complex' experiment
struct Foo {
var numbers = [0,0,0]
subscript(index: Int) -> Int {
get {
return numbers[index]
}
set {
print(numbers[index],newValue)
numbers[index] = newValue
print(numbers[index])
}
}
}
var fooA:Foo! = Foo()
fooA[1] = 1
fooA[1] // 0
// but prints
// 0 1
// 1
for more 'fun'
var fooA:Foo! = Foo()
if var foo = fooA {
foo[1] = 1
print(foo)
}
prints
"Foo(numbers: [0, 1, 0])\n"

Inheritance of property methods (set, get, didSet, willSet, etc.) in Swift

My question is how to deal with inheritance of property methods such as set, get, didSet, willSet, ...?
Let's take an example: I want to override the setter method of a property in a Swift class. Here is what I want to achieve (which is obviously not working):
class A {
var value: Int {get {...} set {...} }
}
class B: A {
var value: Int {
set(newValue) {
// do some fancy stuff...
}
}
}
This is not working, too:
// in class B
override func setValue(newValue: Int) {
// do some fancy stuff...
}
We can do in Swift something like this:
class A {
var _value: Int = 0
var value: Int {
get {
return _value
}
set {
_value = newValue
}
}
}
class B: A {
override var value: Int {
get {
return _value
}
set {
_value = newValue + 1
}
}
}
let a = A()
a.value = 1
print(a.value) // => 1
let b = B()
b.value = 1
print(b.value) // => 2
This approach is not very elegant because I have to implement also the getter methods, which is actually not necessary, because only the setter should be overridden.
You could do:
class A {
var value: Int = 0
}
class B: A {
override var value: Int {
get { return super.value }
set {
// Something fancy...
super.value = newValue
}
}
}
While you still have to implement a getter in B, you at least don't need _value, which helps keeps class A clean.
Unfortunately your only way to do this would be to create a separate get and set method if you really wanted to do this.
class A {
private var value: Int = 0
func getValue() -> Int { return value }
func setValue(newValue : Int) {
value = newValue
}
}
By the nature of using computed properties you are basically doing a "shortcut" in some ways over making two separate methods - and as thus you would have to override both the set and get if you wanted to change things.
Depending on your usage an override of didSet could do the trick (based on your last example):
class B: A {
override var value: Int {
didSet {
_value++
}
}
}