I realize that Go does not have classes but pushes the idea of structs instead.
Do structs have any sort of initialization function that can be called similar to a __construct() function of a class?
Example:
type Console struct {
X int
Y int
}
func (c *Console) init() {
c.X = "5"
}
// Here I want my init function to run
var console Console
// or here if I used
var console Console = new(Console)
Go doesn't have implicit constructors. You would likely write something like this.
package main
import "fmt"
type Console struct {
X int
Y int
}
func NewConsole() *Console {
return &Console{X: 5}
}
var console Console = *NewConsole()
func main() {
fmt.Println(console)
}
Output:
{5 0}
Go does not have automatic constructors. Typically you create your own NewT() *T function which performs the necessary initialization. But it has to be called manually.
This is a Go struct initialize complete:
type Console struct {
X int
Y int
}
// Regular use case, create a function for easy create.
func NewConsole(x, y int) *Console {
return &Console{X: x, Y: y}
}
// "Manually" create the object (Pointer version is same as non '&' version)
consoleP := &Console{X: 1, Y: 2}
console := Console{X: 1, Y: 2}
// Inline init
consoleInline := struct {
X int
Y int
}{
X: 1,
Y: 2,
}
Related
I was having fun while practicing a Kata.
I wanted to implement one of the functions in my solution as an extension of Int, because I liked the idea of having pretty syntax. The function, in itself, looks like this:
func decomposed(_ n: Int) -> [Int] {
if n > 10 {
return n.decomposed(n / 10) + [n % 10]
} else {
return [n]
}
}
Now, I've tried to implement it as an extension. Due to the fact that I would like to use it like 420.decomposed(), I figured that I would need the instance as the default argument. I proceeded with:
extension Int {
func decomposed(_ n: Int = self) -> [Int] {
if n > 10 {
return n.decomposed(n / 10) + [n % 10]
} else {
return [n]
}
}
}
This is the part, however, in which it gets trickier. I'm being told by the compiler that error: cannot find 'self' in scope.
Having read about the methods in the docs, I've resorted to using Int? default argument. Now, the extension is implemented as:
extension Int {
func decomposed(_ n: Int? = nil) -> [Int] {
var _n = n ?? self
if _n > 10 {
return _n.decomposed(_n / 10) + [_n % 10]
} else {
return [_n]
}
}
}
I don't like the look of the _n, though.
I would love to use self as the default argument. Is that possible? Or are we stuck with hackity hacks until the judgement day?
Wrote a quick implementation to highlight the usage of extensions:
import Foundation
func main() {
print(2.test()) // prints 2
print(12.test()) // prints 3
print(42.test()) // prints 6
}
extension Int {
func test() -> Int {
if self <= 10 {
return self
}
return (self % 10) + (self/10).test();
}
}
main()
You don't need to pass self as an argument, since that will not work. By default, self will be available for use inside the extension methods (since that follows the object oriented paradigm).
You need to remove n as a parameter, replace every use of n in the function with self (since that's what's being operated on), and convert the function syntax to the method syntax in the recursion:
extension Int {
func decomposed() -> [Int] {
if self > 10 {
return (self / 10).decomposed() + [self % 10]
} else {
return [self]
}
}
}
In your function decomposed, you aren't using self and n anywhere together you can either make your decomposed method accept no parameter and use self from the function:
extension Int {
func decomposed() -> [Int] {
if self > 10 {
return (self / 10).decomposed() + [self % 10]
} else {
return [self]
}
}
}
or if you plan to pass any parameter then you can just define a top level function instead of using extension:
func intDecomposed(_ n: Int) -> [Int] {
if n > 10 {
return n.decomposed(n / 10) + [n % 10]
} else {
return [n]
}
}
You can use the above method inside the decomposed extension method providing self as parameter:
extension Int {
func decomposed() -> [Int] {
return intDecomposed(self)
}
}
I have come across the array forEach function that is a higher order function and it takes only one parameter, i.e., a closure. Now this closure internally loops through all the elements of the array one by one but does not return anything. The implementation of the closure is left to the choice of the user.
I have a custom class MyClass that has a private variable inside it num and a public function setNum(num: Int) to set the value of that private variable from outside. I am just trying to create a similar function factorial inside my custom class that takes only one parameter, i.e., a closure. However, I have to manually call the closure inside factorial, pass the value of num as a parameter to the closure.
Is there a way that the closure can act on num without having passed it as a parameter? Basically I am just trying to replicate the array forEach function. Syntax of array forEach is:
array.forEach(body: (Int) -> Void) -> Void)
Implementation:
arr1.forEach { print($0) }
My code is as below:
import Foundation
public class MyClass {
private var factorialNumber: Double = 0
internal static var instance: MyClass?
public func setFactorialNumber(number value: Double) {
factorialNumber = value
}
public func factorial(body closure: (String?) -> Void) -> Void {
var outputString: String?
var result: Double = 1
if factorialNumber <= 0 {
outputString = nil
} else {
outputString = ""
while(factorialNumber >= 1) {
if factorialNumber == 1 {
outputString = outputString! + "\(factorialNumber) = \(result)"
break
} else {
outputString = outputString! + "\(factorialNumber) x "
}
result = result * factorialNumber
factorialNumber -= 1
}
}
// Finally closure call
closure(outputString)
}
private init() {}
public static func getInstance() -> MyClass {
if self.instance == nil {
self.instance = MyClass()
}
return self.instance!
}
}
And here is how I have to call my function to calculate the factorial:
var obj1 = MyClass.getInstance()
obj1.setFactorialNumber(number: 5)
obj1.factorial{ (result) in
print(result ?? "Factorial Result is Nil")
}
Please note that I have to pass a parameter result inside my closure to get the result of factorial.
Is there a way that the closure can act on num without having passed it as a parameter? Basically I am just trying to replicate the array forEach function ... [And, in your comment:] All I am trying to do is learn how to create higher order functions like array.forEach.
It's hard to understand what you think you're after, but taking you at your word, let's write forEach. Here we go:
extension Sequence {
func myForEach(f: (Element) -> ()) {
for e in self {
f(e)
}
}
}
Let's test it:
[1,2,3].myForEach { print($0) } // prints 1, then 2, then 3
We've done it! We wrote a higher-order function that acts exactly like forEach. So this must be how forEach actually works, more or less.
You can see from the example that it makes no sense to ask not to have to pass a parameter into the function that our forEach takes as a parameter. That is exactly what we must be able to do in order for that function to have an element to operate on.
I need to start the same random number list over every execution of my app.
srand/rand do not exist anymore. What should I do then?
private extension Array {
private func randomValues(_ seed: UInt32, num: Int) -> [Element] {
srand (seed)
var indices = [Int]()
indices.reserveCapacity(num)
let range = 0..<self.count
for _ in 0..<num {
var random = 0
repeat {
random = randomNumberInRange(range)
} while indices.contains(random)
indices.append(random)
}
return indices.map { self[$0] }
}
You can use
srand48(seed) and drand48() in Swift3.
Unless you're developing with Swift for non-Apple platforms, you can get a much better randomization API in GameplayKit: several algorithms (trade randomness vs speed), seedable, distribution control, etc.
I can't find a way to use seeded random in Swift 3 Beta 1. Had to write a silly wrapper function in C:
// ----------------------------------------------
// my_random.h
// ----------------------------------------------
#ifndef my_random_h
#define my_random_h
#include <stdio.h>
#endif /* my_random_h */
long next_random();
// ----------------------------------------------
// my_random.c
// ----------------------------------------------
#include <stdlib.h>
#include "my_random.h"
long next_random() {
return random();
}
You can use the bridging header to import it into Swift. Then you can call it in Swift like this:
srandom(42)
for _ in 0..<10 {
let x = next_random()
print(x)
}
random is better than rand. Read the man pages for discussion on these 2 functions.
Edit:
A workaround, as #riskter suggested, is to use GameKit:
import GameKit
let seed = Data(bytes: [42]) // Use any array of [UInt8]
let source = GKARC4RandomSource(seed: seed)
for _ in 0..<10 {
let x = source.nextInt()
print(x)
}
For a simple repeatable random list try using a Linear Congruential Generator:
import Foundation
class LinearCongruntialGenerator
{
var state = 0 //seed of 0 by default
let a, c, m, shift: Int
//we will use microsoft random by default
init() {
self.a = 214013
self.c = 2531011
self.m = Int(pow(2.0, 31.0)) //2^31 or 2147483648
self.shift = 16
}
init(a: Int, c: Int, m: Int, shift: Int) {
self.a = a
self.c = c
self.m = m //2^31 or 2147483648
self.shift = shift
}
func seed(seed: Int) -> Void {
state = seed;
}
func random() -> Int {
state = (a * state + c) % m
return state >> shift
}
}
let microsoftLinearCongruntialGenerator = LinearCongruntialGenerator()
print("Microsft Rand:")
for i in 0...10
{
print(microsoftLinearCongruntialGenerator.random())
}
More info here:
https://rosettacode.org/wiki/Linear_congruential_generator
I just happened to put this together for Swift 4. I am aware Swift 4.2 has new random extensions that are different from this, but like the OP, I needed them to be seedable during testing. Maybe someone will find it helpful. If you don't seed it, it will use arc4random, otherwise it will use drand48. It avoids mod bias both ways.
import Foundation
class Random {
static var number = unseededGenerator // the current generator
/**
* returns a random Int 0..<n
**/
func get(anIntLessThan n: Int) -> Int {
return generatingFunction(n)
}
class func set(seed: Int) {
number = seedableGenerator
srand48(seed)
}
// Don't normally need to call the rest
typealias GeneratingFunction = (Int) -> Int
static let unseededGenerator = Random(){
Int(arc4random_uniform(UInt32($0)))
}
static let seedableGenerator = Random(){
Int(drand48() * Double($0))
}
init(_ gf: #escaping GeneratingFunction) {
self.generatingFunction = gf
}
private let generatingFunction: GeneratingFunction
}
func randomTest() {
Random.set(seed: 65) // comment this line out for unseeded
for _ in 0..<10 {
print(
Random.number.get(anIntLessThan: 2),
terminator: " "
)
}
}
// Run
randomTest()
Given the below struct in Swift, is there a more concise way to alias the instance variables x, y, and z to the properties of the three-tuple, _v?
Note: I realize that, of course, I could just declare these instance variables as Doubles and not need the tuple. However, the reason I'm doing it this way is so I can set three variables with a single-line statement like you will see in the init method and the below sample code.
Sample code with desired output of "1.0" "4.0":
var myVector = Vector3([1.0,2.0,3.0])
let x = myVector.x
print(x)
myVector.v = (4.0,5.0,6.0)
print(x)
The class:
struct Vector3 {
typealias V3 = (x:Double,y:Double,z:Double)
var v:V3 = (x:0.0,y:0.0,z:0.0)
var x:Double {
get {
return v.x
}
set(x) {
v.x = x
}
}
var y:Double {
get {
return v.y
}
set(y) {
v.y = y
}
}
var z:Double {
get {
return v.z
}
set(z) {
v.z = z
}
}
init(_ args:AnyObject...) {
if(args[0].isKindOfClass(NSArray)) {
v = (args[0][0].doubleValue,args[0][1].doubleValue,args[0][2].doubleValue)
}
else if(args.count == 3){
v = (args[0].doubleValue,args[1].doubleValue,args[2].doubleValue)
}
}
}
What I would like to be able to do is:
struct Vector3 {
typealias V3 = (x:Double,y:Double,z:Double)
var v:V3 = (x:0.0,y:0.0,z:0.0)
alias x = v.x
alias y = v.y
alias z = v.z
init(_ args:AnyObject...) {
if(args[0].isKindOfClass(NSArray)) {
v = (args[0][0].doubleValue,args[0][1].doubleValue,args[0][2].doubleValue)
}
else if(args.count == 3){
v = (args[0].doubleValue,args[1].doubleValue,args[2].doubleValue)
}
}
}
Of course that doesn't work. But is there another way to achieve the same thing?
Just do the opposite!
I realize that, of course, I could just declare these instance variables as Doubles and not need the tuple. However, the reason I'm doing it this way is so I can set three variables with a single-line statement like you will see in the init method and the below sample code.
If this is the reason then just do the opposite
struct Vector3 {
var x: Double
var y: Double
var z: Double
var coordinates: (Double, Double, Double) {
set { (x, y, z) = newValue }
get { return (x, y, z) }
}
}
Usage
var vector = Vector3(x: 1, y: 2, z: 3)
vector.x = 4
vector.coordinates // (4, 2, 3)
Final note
Your initializer could be improved in several ways.
Stop using NSArray, you are using Swift not Objective-C
Stop using isKindOfClass, use as? to perform a conditional cast
You have faith the objects inside the first array/s will have a doubleValue property. So I could easily crash your init passing something different right?
Now my question
What's wrong with the memberwise struct initializer?
It is automatically generated when you don't explicitly define an initializer for a struct, like in my previous code snipped.
Are you sure you want to define an initializer that literally accept any sort of objects an will crash with 99.99% of the combinations of values someone can pass to it?
Assume the following:
class A {
let x : Int
init() {
self.x = assign(1)
}
func assign(y : Int) -> Int {
return y
}
}
This produces an error.
Here is my question : is there a way to call functions within the class initializer?
EDIT: Added error message:
use of 'self' in method call 'assign' before all stored properties are initialized
You can't call instance methods until the instance is initialized (before init is done), but you can use module-level functions and type methods defined using the class or static keyword.
func compute(y: Int) -> Int {
return y
}
class A {
let x: Int
static func assign(y: Int) -> Int {
return y
}
init () {
x = A.assign(3) + compute(4)
}
}
One other (possibly helpful) option is to have the function you call within the initializer scope:
class A {
let x : Int
init() {
func assign(y : Int) -> Int {
return y
}
self.x = assign(y: 1)
}
}
I'm doing that in a project right now. I have a large initializer (its actually a parser) and use an initializer-scoped function for error reporting. Of course, I'd prefer the function to be at class scope so I can reuse it between initializers. But at least I can reuse it within each initializer.
I think it is not the greatest solution but still it is working.
class A {
var variable : Int
init() {
self.variable = A.assign(1)
}
private class func assign(y : Int) -> Int {
return y
}
}
You could use somethings like:
class A {
var x : Int!
init() {
x = assign(1)
}
func assign(y : Int) -> Int {
return y
}
}
The downside of this approach is that you will get a runtime error if you access x and it is not initialised. Check out this answer.