I have a Swift Class called Person and it has three values: First name, last name and birthday (String, String and NSDate). Now I have function which I want to use to print something based on an attribute - for example when the attribute is myPerson.name it should print the following: This person's name is .... My question is now is it possible to make a function which takes a parameter of the class Person as parameter? For example: func myFunction(parameter:Person.parameter) {} (I know there's no Person.parameter but it's just an example).
I know there are easier solutions but it would be helpful for me for another project. Thank in advance.
You can create a new property name and override it's getter to return 'This person's name is ... ' text,
class Person{
let firstName: String
let lastName: String
init(firstName: String, lastName: String) {
self.firstName = firstName
self.lastName = lastName
}
var name: String {
get {
return "This person's name is \(firstName) \(lastName)"
}
}
}
let person = Person(firstName: "Sandeep", lastName: "Koirala")
person.name
Regarding the function, you can create a new function which takes Person as object and then perform some calculation on its property like this,
func printPersonsName(person: Person) {
print(person.name)
}
Related
How can I pass the value of all key from object as functions parameters? like python did.
I have one function getNameInfo with parameter with default value firstName, lastName, age and one object with key firstName, lastName, age how is the best way for me to descture the pbject and pass all value of key into function? in python i can do something like getNameInfo(**a.__dict__.values()) but
class Person {
public var firstName = "firstName"
public var lastName = "lastName"
public var age = 12
public init(firstName: String, lastName: String, age: Int){
self.firstName = firstName
self.lastName = lastName
self.age = age
}
}
let a = Person(firstName: "firstName", lastName: "lastName", age: 12)
func getNameInfo(firstName: String = "i am first", lastName: String = "I am lat", age: Int = 50) {
print("\(fName), \(lName), \(age)")
}
getNameInfo()
// getNameInfo(a) // expect to print out firstName, lastName, 12
There is no similar feature in Swift. The closest version is to use protocols:
protocol NameInfoProviding {
var firstName: String { get }
var lastName: String { get }
var age: Int { get }
}
extension Person: NameInfoProviding {}
func getNameInfo(_ nameInfo: some NameInfoProviding) {
print("\(nameInfo.firstName), \(nameInfo.lastName), \(nameInfo.age)")
}
getNameInfo(a)
But yes, this is a different feature and used in different ways.
I am using Mirror to access the children of my struct like this:
struct TestType {
var firstName: String
var lastName: String
var value: String {
return firstName + lastName
}
}
use case:
let person: TestType = TestType(firstName: "Tim", lastName: "Cook")
for property in Mirror(reflecting: person).children {
print("label: \(property.label!)", "value: \(property.value)")
}
results:
label: firstName value: Tim
label: lastName value: Cook
Now my goal is do the same thing for the person constant as well, with that said, I want be able to access the label of person which is person and the value of it, the result should look like this:
label: person value: Tim Cook
How can i do this in Swift?
Honestly I have no idea why need to use Mirror here) would be great if you would describe it in as a comment below this answer. I would appreciate it)
but the reason why you can't what you need is because of Mirror can't see computed properties, as far as I know. Any way you can customise your init method to reach what you need. But remember that using Mirror is too expensive, for example: if it in inherited object it will parse every single thing in parent classes which could be accessible for Mirror
struct TestType {
let firstName: String
let lastName: String
let person: String
init(firstName: String, lastName: String) {
self.firstName = firstName
self.lastName = lastName
person = [firstName, lastName].joined(separator: " ")
}
}
class person {
var name : String
init(name: String) {
self.name = name
}
}
I am learning Swift class chapter
I don't understand why init(name:String) self.name = name code is needed
what the purpose of this code is.
I declared var name: String
and again init(name: String), why is self.name = name needed?
what's different between just var name and self.name = name?
Look into something called variable scope. In your code - there are two "name variables - a class (or instance) variable and a "parameter in your init.
The latter - init(name:) only is in use within your initialization function, meaning the instance has no name without the self.name = name once you've created the instance.
The former is available - to the instance - as long as your instance of the class person is.
To explain further, try this. Change your code to be:
class Person {
var myName : String
var myOtherName : String
init(name: String) {
self.myName = name
}
}
In your app or view controller, do this:
let myPerson = Person(name: "john")
print(myPerson.myName) // prints "jihoon"
print(myPerson.myOtherName) // prints nothing
print(myPerson.name) // generates a build error because name doesn't exist
One last note - in Swift class names are capitalized, so the best name is Person, not person.
Classes and structures must set all of their stored properties to an appropriate initial value by the time an instance of that class or structure is created. Stored properties cannot be left in an indeterminate state.
class person {
var name : String // undetrmined state
init(name: String) {
self.name = name
}
}
class person2 {
var name : String = "default value" // detrmined state
// Now these intializer are not optional. You can use these initializer or not.
init(name: String) {
self.name = name
}
init() {
}
}
// Aother example for optional stored property
class person3 {
var name : String? // detrmined state, because default value for optional is nil
// Now these intializer are not optional. You can use these initializer or not.
init(name: String) {
self.name = name
}
init() {
}
}
For more info read this one Apple Doc
I have two classes (to simplify I drop other filed the object is more complicated then the Person):
class Person
{
var name: String = "Default name"
init(object: PersonEntity)
{
name = object.daysMask
}
}
class Employer: Person
{
}
I have function that configure for me a person
func getConiguratedPerson(name: String) -> Person
{
let person = Person()
person.name = name
}
In case if I want to get Person I simple do this:
let person = getConiguratedPerson("Alex")
but what if I need Employer instead and I want to use this function as well
let employer = getConiguratedPerson("Alex") // returns Person as expected but need to have employer instead.
In Objective-C we can simple do this:
Employer *employer = Employer([self getConiguratedPerson:"Alex"]) if I remember.
The mistake is the getConfiguredPerson function. You want an initializer. Initializers return your own class, which is exactly what you want.
class Person {
var name: String = "Default name"
init(name: String) {
self.name = name
}
init(object: PersonEntity) {
self.init(object.daysMask)
}
}
class Employer: Person {}
Now to create a person, you just use Person(name: "Alex") and to get an employer you use Employer(name: "Alex").
Note that this is true in ObjC as well. You shouldn't have getConfiguredPerson there either. You'd should have [Person initWithName:].
You can't use upcasting here, because configured person is not of Employee type, but of Person type. To achieve the desired result I would suggest something like this:
class Person {
var name = "name"
required init() { }
}
class Employee: Person { }
func getPerson<T: Person>(name: String) -> T {
let person = T()
person.name = name
return person
}
let employee: Employee = getPerson("Alex")
or this if type of object returning by factory method depends on input:
func getPerson(name: String) -> Person {
if name != "Alex" {
return Person()
}
return Employee()
}
let employee = getPerson("Alex") as! Employee
Having array of employee object, called employees and now I want to create another array called filteremployees which is having only id and date of birth value.
Using
let filteremployees = employee.map({ $0.id})
I can get array which contains only id value but i want to have id as well dateOfBirth
class Employee {
var id: Int
var firstName: String
var lastName: String
var dateOfBirth: NSDate?
init(id: Int, firstName: String, lastName: String) {
self.id = id
self.firstName = firstName
self.lastName = lastName
}
}
Try this:
let employees : [Employee] = ...
let list: [(Int, NSDate?)] = employees.map { ($0.id, $0.dateOfBirth) }
You must explicitly declare the type of list otherwise you get this error from the compiler
Type of expression is ambiguous without more context.
Tested with Xcode 7 Playground and Swift 2.0.
Hope this helps.
You could try using the same map method and returning a tuple of your expected values:
let filter employees: [(Int, NSDate?)] = employee.map({ ($0.id, $0.dateOfBirth) })
Alternatively, and I think this is a better solution, create a new value type and create that with only your required values
struct FilteredEmployee {
let id: String
let dateOfBirth: NSDate?
init(employee: Employee) {
id = employee.id
dateOfBirth = employee.dateOfBirth
}
}
And then you can map the initialiser over the array
let filteremployees = employee.map { FilteredEmployee($0) }