How to dynamically create instances of objects in F# - class

I am having trouble finding out how to create a function that creates and instance of an object where the name of the variable that holds the function is specified in the parameter of the function.
I am writing an assignment where I do not know how many instances of the object that is to be created. I know how to call the constructor in a function, but I do not know how to give each instance a unique name?
let test() = class
let variable = 1
end
let createInstance (name : string) =
let name = new Test()
This is just a test example. This is what I have tried, but the function does not parse the string "name" to be the name of the object instance variable.
Thanks!

Related

Whats the difference between initializing a variable within a class VS without??? - swift

Here's my problem, I have a variable that I initialize once so that I don't have to call the database every time I want to use that variable. How should I structure it? Example 1 or 2? What's the difference between putting functions and variables inside a class vs without a class?
example 1 (no class):
import UIKit
var username = ""
func callToDatbase () {
// I run my code to set the username value equal to stored username value within the database
//Ex: username = database.username
}
---------------------------------------------------------------------------------------------------------
//Then when I want to call it in another view controller I would just say:
usernameLabel.text = username
Example 2 (with class):
import UIKit
class Initializers {
var username = ""
func callToDatbase () {
// I run my code to set the username value equal to stored username value within the database
//Ex: self.username = database.username
}
}
---------------------------------------------------------------------------------------------------------
//Then when I want to call it in another view controller I would just say:
usernameLabel.text = Initializers().username
When you initialise a variable outside of the class it is store in the global scope. The scope in swift is defined by the curly brackets, so you can think about the outside of the class as the whole project surrounded by the curly brackets. When you define the variable inside of the class it is only going to be available from that class when you instantiate it as an object. You might want to read about inheritance to find out what else you can do with variables in classes.
TLDR: Variable outside will be available to the whole code, whereas the one inside the class will only be available from within the class or by accessing it as a property from instantiated object.
Example code:
class Example {
var name = "Antoni"
}
print(name) // Will throw error
let example = Example() // Create an instance of the class
print(example.name) // Prints as expected
It is preferred to put variables in some sort of instantiable/destructible structure like a class to help swift with memory management. The variables defined globally will not be removed from memory until the program exits. And if you need to store static variables use struct instead.

Can you use an object's instance address as the key in objc_setAssociatedObject?

Normally when using objc_setAssociatedObject, the recommended practice is to create a static variable, then use its address (via the '&' prefix) as the key.
However, we have a case where we need to associate an arbitrary number of classes with one 'owner' class, and as such, each needs its own unique key. My thought was to use the actual address of the class instance for that purpose.
The issue I'm running into is I can only seem to get the address as an Int, but the function expects an UnsafeRawPointer and I haven't found any code that lets me initialize, or convert to one from an int.
So again, while I can get the address as an int with this code...
func addressOf<T: AnyObject>(_ object: T) -> Int {
return unsafeBitCast(object, to:Int.self)
}
let classA = MyClass()
let classB = classA
let a = addressOf(classA)
let b = addressOf(classB)
// Result: a == b
I can't get a/b as an UnsafeRawPointer. Is this even possible?

Global 'let' declaration requires an initializer expression

I am working on iOS code with Xcode 10.2.1.
I have an issue when declaring a let global variable:
import UIKit
import CouchbaseLiteSwift
private let database: Database
This gives the compiler error below:
Global 'let' declaration requires an initializer expression
I don't know how to make database a global variable in this case. I searched about it, but all says about some int or string initialization but not when initializing classes like Database. Because, Couchbase's Database class is a big class. I can't do it with "= null"
Any help please?
You need a variable if you're not sure what it is so that later you can change it:
private var database: Database?
There's no point in defining a constant if you're not going to actually define it as something.
The distinguishing feature of a let variable is that it is assigned to exactly once before being read.
When a let declaration is a local variable, Swift can analyze the code to make sure that the variable will be initialized exactly once before it is used. This is why you can declare a local let variable with no initial value. For example:
let greeting: String
if(light.isOn()) {
greeting = "Hello!"
} else {
greeting = "Who’s there?!"
}
// Now it is OK to use greeting, because we _know_ the code took
// exactly one branch of the if, and each branch initializes greeting
print(greeting) // OK
With an instance variable, you don't need to specify an initial value as long as every initializer sets it exactly once.
However, with a global variable, the compiler can't really make any guarantees about who will assign to it when. You therefore have to give it an initial value right on the spot.
As #rmaddy points out in the comments, it might look like this:
private let database = Database(name: "foo")
If initialization takes multiple statements, you can batch them up in a closure like this:
private let database = {
let config = readConfigFile()
guard let dbName = config["database"] else {
fatalError("Missing config for 'database'")
}
return Database(name: dbName)
}()
If you must make it a global, but it just isn't possible to initialize it until later, you must make it a var:
private var database: Database?
…or if you want any attempt to use it before it’s initialized to be a crasher:
private var database: Database!

Swift, when referencing a class property, is it making a copy of the data?

So I'm a little confused because of conflicting information, just looking for some clarity regarding memory allocation for Class properties.
So here are my assumptions, please let me know if any of them are wrong:
In Swift, except for Classes and Functions, everything is passed by Value.
Classes instances (objects) are allocated on the Heap
When you pass an object around, you are passing the pointer
When you reference a property on an object, the pointer is dereferenced, and the value of the property is retrieved
So here's my confusion, say my class has a String property, and an Int property. Both Swift data types, that get passed by value in any ordinary situation.
If I ask for let test = object.stringProperty, am I going to get a copy of my string value copied into my test variable?
Similarly, if I had a method inside of my class,
func getAllProperties() -> (String, Int) {
return (self.stringProperty, self.intProperty)
}
is object.getAllProperties() going to return a copy of the properties in a tuple?
I know it seems like a basic question, but after reading several sources I just ended up more uncertain than when I started
Yes and yes. It doesn't matter that the String and the Int were in a class. You asked for the String or the Int (or both), those are value types, you got copies.
It's easy to prove this to yourself, especially with the String. Just change something about it, and then look back at what the class instance is holding: it will be unchanged.
class C {
var stringProperty : String
init(string:String) {
self.stringProperty = string
}
}
let c = C(string:"hello")
var s = c.stringProperty
s.removeLast()
print(s) // hell
print(c.stringProperty) // hello
If you want to see the class-as-reference in action, make two of the same instance and do something to one of those:
class C {
var stringProperty : String
init(string:String) {
self.stringProperty = string
}
}
let c = C(string:"hello")
let d = c
c.stringProperty = "goodbye"
print(d.stringProperty) // goodbye

Swift: get the compile time name of variable (referencing to a class)

Is there a way to get the compile time name of a variable in Swift 2?
I mean the first variable name, which references to a new class instance, if any.
Here is a simple example:
public class Parameter : FloatLiteralConvertible {
var name:String?
var value:Double
// init from float literal
public required init (floatLiteral value: FloatLiteralType) {
self.value = Double(value)
self.name = getLiteralName()
}
func getLiteralName () -> String {
var literalName:String = ""
// do some magic to return the name
return literalName
}
}
let x:Parameter = 2.0
print(x.value) // this returns "2.0"
print(x.name!) // I want this to return "x"
I've already checked similar questions on that topic handling mirroring or objective-c reflections. But in all those cases, one can get only the property names in a class - in the example above name and value.
The same question has been asked in 2014 - Swift: Get Variable Actual Name as String
- and I hope, that since then there is a solution in swift 2.
No, there is no way to do that.
You have to understand that in the compiled state that variable usually does not exist. It can be optimized out or it is represented only as an item on the execution stack.
Even in languages with much better reflection that Swift has, usually you cannot inspect local variables.
To be honest, getting the name of a local variable dynamically has no practical use case.