Just started looking at Swift this weekend. I'm creating an id for my class to quickly compare objects. I want an immutable id, so should use let.
刚开始看这个周末的Swift。我正在为我的班级创建一个id来快速比较对象。我想要一个不可变的id,所以应该使用let。
Using var and initialising id to "" will fix "use of self in method call before stored properties are initialised" but then of course it's mutable. Every other question i've seen similar to this is regarding a super class / calling super.init, which I don't have. It's very frustrating, I don't know why it's not straightforward.
使用var和初始化id为“”将修复“在初始化存储属性之前在方法调用中使用self”,但当然它是可变的。我见过的所有其他问题都与超级/调用super.init有关,我没有。这非常令人沮丧,我不知道为什么它不直接。
class MagicCard {
let id:String
let name: String
let manaCost: Int
let description: String
let attack: Int
let defence: Int
init (name: String, manaCost: Int, description: String, attack: Int, defence: Int) {
self.name = name
self.manaCost = manaCost
self.description = description
self.attack = attack
self.defence = defence
id = generateRandomID()
}
private func generateRandomID() -> String {
let charSet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let charSetArray = Array(charSet.characters)
var id:String = ""
for _ in (0..<10) {
id.append(charSetArray[Int(arc4random()) % charSetArray.count])
}
return id
}
}
func == (lhs: MagicCard, rhs: MagicCard) -> Bool {
return lhs.id == rhs.id
}
3 个解决方案
#1
8
The generateRandomID()
method does not use or modify any properties of the instance, so one possible solution would be to make it a type (class) method:
generateRandomID()方法不使用或修改实例的任何属性,因此一种可能的解决方案是使其成为类型(类)方法:
private class func generateRandomID() -> String {
// ...
return id
}
and use it like
并使用它
id = MagicCard.generateRandomID()
(as also written in the other answer while I was writing this).
(在我写这篇文章的时候也写在另一个答案中)。
You could also drop the method and use an "immediately evaluated closure":
您也可以删除该方法并使用“立即评估的闭包”:
id = { () -> String in
// ...
return id
}()
But if the intention of the id property is to make the objects Equatable
then you don't need it at all. Classes are reference types and instances can be compared with the "identical to" operator:
但是如果id属性的意图是使对象成为Equatable,那么根本不需要它。类是引用类型,实例可以与“相同”运算符进行比较:
func == (lhs: MagicCard, rhs: MagicCard) -> Bool {
return lhs === rhs
}
which makes the id
and the generateRandomID()
method obsolete.
这使得id和generateRandomID()方法过时了。
#2
9
A hot-fix I can suggest is to make generateRandomID
a class func. So make it like so :
我可以建议的一个热门修复是使generateRandomID成为类func。所以这样做:
private class func generateRandomID() -> String {
And call like this :
并且这样打电话:
id = MagicCard.generateRandomID()
#3
3
Calling the member function generateRandomID
includes an implicit self.
, so you cannot indeed do it before the object is fully initialised. A simple solution would be first assigning a temporary value to id
:
调用成员函数generateRandomID包含一个隐式self。,因此在对象完全初始化之前你无法做到这一点。一个简单的解决方案是首先为id分配一个临时值:
id = ""
id = generateRandomID() // NOT THE SUGGESTED SOLUTION, see below.
But to do that you'd have to change it to a var
, and then it'd take more effort to hide the setter from the public.
但要做到这一点,你必须将其更改为var,然后需要更多的努力来隐藏公众的设置者。
However, nothing in generateRandomID()
depends on the state of the object, so it might as well be a static
class function, which you would then call as MagicCard.generateRandomID()
. But to take it even further, conceptually the generation of a random id doesn't have anything to with a Magic card, so you could even make it a global function or isolate it to a class of its own…
但是,generateRandomID()中没有任何内容取决于对象的状态,因此它也可能是一个静态类函数,然后您将其称为MagicCard.generateRandomID()。但是更进一步,从概念上讲,随机id的生成与Magic卡没有任何关系,所以你甚至可以将它作为一个全局函数或将它隔离到它自己的类......
…and once we get that far, why not just use the existing NSUUID
type to represent your id? Either change the type of id
to NSUUID
and initialise it with id = NSUUID()
for a random UUID, or keep it a String
and assign as id = NSUUID().UUIDString
. UUIDs already solve the problem of unique ids, so you don't have to come up with your own generator. =)
...一旦我们走到那么远,为什么不使用现有的NSUUID类型来表示你的身份?将id的类型更改为NSUUID并使用id = NSUUID()为随机UUID初始化它,或者将其保留为String并指定为id = NSUUID()。UUIDString。 UUID已经解决了唯一ID的问题,因此您不必提出自己的生成器。 =)
This leads us to:
这导致我们:
let id: NSUUID = NSUUID()
or
要么
let id: String = NSUUID().UUIDString
#1
8
The generateRandomID()
method does not use or modify any properties of the instance, so one possible solution would be to make it a type (class) method:
generateRandomID()方法不使用或修改实例的任何属性,因此一种可能的解决方案是使其成为类型(类)方法:
private class func generateRandomID() -> String {
// ...
return id
}
and use it like
并使用它
id = MagicCard.generateRandomID()
(as also written in the other answer while I was writing this).
(在我写这篇文章的时候也写在另一个答案中)。
You could also drop the method and use an "immediately evaluated closure":
您也可以删除该方法并使用“立即评估的闭包”:
id = { () -> String in
// ...
return id
}()
But if the intention of the id property is to make the objects Equatable
then you don't need it at all. Classes are reference types and instances can be compared with the "identical to" operator:
但是如果id属性的意图是使对象成为Equatable,那么根本不需要它。类是引用类型,实例可以与“相同”运算符进行比较:
func == (lhs: MagicCard, rhs: MagicCard) -> Bool {
return lhs === rhs
}
which makes the id
and the generateRandomID()
method obsolete.
这使得id和generateRandomID()方法过时了。
#2
9
A hot-fix I can suggest is to make generateRandomID
a class func. So make it like so :
我可以建议的一个热门修复是使generateRandomID成为类func。所以这样做:
private class func generateRandomID() -> String {
And call like this :
并且这样打电话:
id = MagicCard.generateRandomID()
#3
3
Calling the member function generateRandomID
includes an implicit self.
, so you cannot indeed do it before the object is fully initialised. A simple solution would be first assigning a temporary value to id
:
调用成员函数generateRandomID包含一个隐式self。,因此在对象完全初始化之前你无法做到这一点。一个简单的解决方案是首先为id分配一个临时值:
id = ""
id = generateRandomID() // NOT THE SUGGESTED SOLUTION, see below.
But to do that you'd have to change it to a var
, and then it'd take more effort to hide the setter from the public.
但要做到这一点,你必须将其更改为var,然后需要更多的努力来隐藏公众的设置者。
However, nothing in generateRandomID()
depends on the state of the object, so it might as well be a static
class function, which you would then call as MagicCard.generateRandomID()
. But to take it even further, conceptually the generation of a random id doesn't have anything to with a Magic card, so you could even make it a global function or isolate it to a class of its own…
但是,generateRandomID()中没有任何内容取决于对象的状态,因此它也可能是一个静态类函数,然后您将其称为MagicCard.generateRandomID()。但是更进一步,从概念上讲,随机id的生成与Magic卡没有任何关系,所以你甚至可以将它作为一个全局函数或将它隔离到它自己的类......
…and once we get that far, why not just use the existing NSUUID
type to represent your id? Either change the type of id
to NSUUID
and initialise it with id = NSUUID()
for a random UUID, or keep it a String
and assign as id = NSUUID().UUIDString
. UUIDs already solve the problem of unique ids, so you don't have to come up with your own generator. =)
...一旦我们走到那么远,为什么不使用现有的NSUUID类型来表示你的身份?将id的类型更改为NSUUID并使用id = NSUUID()为随机UUID初始化它,或者将其保留为String并指定为id = NSUUID()。UUIDString。 UUID已经解决了唯一ID的问题,因此您不必提出自己的生成器。 =)
This leads us to:
这导致我们:
let id: NSUUID = NSUUID()
or
要么
let id: String = NSUUID().UUIDString