Swift '(int, int) -> $T4' is not identical to 'Point' - xcode

I'm fairly new to swift and get this error. All I want the declaration to do is assign the 4 values to create 2 Point objects for a Line object. So Line(10, 20, 20, 40) should create two points at (10,20) and (20,40). But I get the error '(Int, Int) -> $T4' is not identical to 'Point'
class Point {
var x: Int = 0
var y: Int = 0
init(){
x = 0
y = 0
}
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
class Line: Point {
var pointA: Point
var pointB: Point
init(p1x: Int, p1y: Int, p2x: Int, p2y: Int) {
self.pointA(p1x, p1y)
self.pointB(p2x, p2y)
}
}
var lineA = Line(p1x:10, p1y:20 , p2x:20 , p2y:40)

Your code in Line's init is meaningless. This is not valid Swift:
self.pointA(p1x, p1y)
self.pointB(p2x, p2y)
You can't just stick parentheses after the name of a variable like that! Plus you are not writing your init correctly. Here's a possible fix:
class Line: Point {
var pointA: Point
var pointB: Point
init(p1x: Int, p1y: Int, p2x: Int, p2y: Int) {
self.pointA = Point(x:p1x, y:p1y)
self.pointB = Point(x:p2x, y:p2y)
super.init()
}
}
But as Antonio has already said, it all depends on what you're trying to do. My code above will cause your code to compile correctly, but I have no idea whether it does what you want, because what you're trying to do is utterly impossible to guess.

In the initializer you are missing to create instances - you are just trying to reference 2 properties as if they were methods. The correct way is:
init(p1x: Int, p1y: Int, p2x: Int, p2y: Int) {
self.pointA = Point(x: p1x, y: p1y)
self.pointB = Point(x: p2x, y: p2y)
}
There is an architectural mistake though: Line inherits from Point, but I see no relationship between the 2 classes - you should at least call the superclass initializer, but what to pass?
I would instead define only 1 new property in Line, and reuse the property already available in Point:
class Line: Point {
var pointB: Point
init(p1x: Int, p1y: Int, p2x: Int, p2y: Int) {
self.pointB = Point(x: p2x, y:p2y)
super.init(x: p1x, y: p1y)
}
}
I don't know if that makes sense (depending on what you want to achieve) - if not, then I would just make Line not inherit from Point. If you need a common interface, but with different implementations, then you can use a protocol adopted by the 2 classes.

Related

Override string conversion for custom classes in Nim

Is it possible to override whatever method is used when an object of a custom class is converted to a string for display?
For example, this code currently prints (x: 4, y: 5), but I want it to print just (4,5)
type Point = object
x: int
y: int
let p = Point(x:4, y:5)
echo p
What proc/method/whatever do I implement to change the default Point->string conversion used by echo?
Figured it out; echo's docs says you just gotta overload the $ operator:
from strformat import fmt
type Point = object
x: int
y: int
proc `$`(point: Point): string = fmt"({point.x}, {point.y})"
let p = Point(x:4, y:5)
echo p # prints "(4, 5)"

Cannot convert value of type 'CLLocationDirection' (aka 'Double') to expected argument type 'Float'

I have this code and its giving me and error Cannot convert value of type 'CLLocationDirection' (aka 'Double') to expected argument type 'Float' on arrowImageView.transform = CGAffineTransformMakeRotation(CGFloat(self.degreesToRadians(direction))). Please help me fix. Thank you.
func locationManager(manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
var direction: CLLocationDirection = newHeading.magneticHeading
if direction > 180 {
direction = 360 - direction
}
else {
direction = 0 - direction
}
// Rotate the arrow image
if let arrowImageView = self.arrowImageView {
UIView.animateWithDuration(1.0, animations: { () -> Void in
arrowImageView.transform = CGAffineTransformMakeRotation(CGFloat(self.degreesToRadians(direction)))
})
And would it also be possible to make the compass point to a longitude and latitude specified by the user? Could you please teach me how. Thanks a lot.
Swift's primitive types are not interchangeable (unlike in Objective-C)
Either you make your degreesToRadians function conform also to Double
or you have to create a Float from direction
arrowImageView.transform = CGAffineTransformMakeRotation(CGFloat(self.degreesToRadians(CGFloat(direction))))

Expected Declaration Swift (Sprite Kit)

I'm using Xcode 7 with swift and when I type
class Block {
var Block = SKShapeNode(circleOfRadius: 15)
Block.fillColor = SKColor.redColor() //Error Here
Block.physicsBody = SKPhysicsBody(circleOfRadius: 15)
Block.physicsBody?.affectedByGravity = true
Block.physicsBody?.restitution = 0
Block.physicsbody?.LinearDamping = 0
self.addChild(Block)
It gives me an error that says "expected declaration" (on the line with the comment) and I don't know why
There are some errors:
You have a class and are trying to change class properties outside the scope of a method or an initializer.
The line Block.physicsbody?.LinearDamping = 0 should be Block.physicsBody?.linearDamping = 0; case-sensitivity.
You name your SKShapeNode instance as Block, the same name as your class. By naming convention, class (type) names begin with Capital letters, whereas class properties use small letters in their names.
With these three fixed, we can proceed to looking at your scene.
With help from Leo Dabus (thanks!), we should have enough to set you up with a minimal working example (using your code) of the SKScene:
class GameScene: SKScene {
override func didMoveToView(view: SKView) {
let block = SKShapeNode(circleOfRadius: 15)
// you will also need to set your node initial position
// if you would like your red circle to fall from the middle of the top of your scene you need to use the scene frame midX and maxY (not the view frame). the scene it is not necessarily the same size of your view)
block.position = CGPoint(x: scene!.frame.midX, y: scene!.frame.maxY)
block.fillColor = SKColor.redColor()
block.physicsBody = SKPhysicsBody(circleOfRadius: 15)
block.physicsBody?.affectedByGravity = true
block.physicsBody?.restitution = 0
block.physicsBody?.linearDamping = 0
self.addChild(block)
}
// ...
}

Getting an Instance from 'unsafeAddressOf'

I encode an Int64 (on the graphics card) with unsafeAddressOf of some instances (that are properly stored in and retained by some array).
I then would like to get back to my instances from my Int64. I manage to get an UnsafePointer<MyClass> correctly initialized from my Int64.
Then, I do:
let x = UnsafePointer<MyClass>.memory.
But using x crashes.
I understand it is unsafe and tricky considering ARC. But still, is there any way to achieve this in Swift, or is it helpless?
Thanks.
What you are trying to do is extremely unsafe, as you yourself said, and there are probably safer approaches to solving whatever problem you are working on, but here is a complete example that does it:
func getPointer<T:AnyObject>(obj : T) -> Int64
{
return unsafeBitCast(unsafeAddressOf(obj), Int64.self)
}
func recoverObject<T:AnyObject>(ptr : Int64) -> T
{
return Unmanaged<T>.fromOpaque(COpaquePointer(bitPattern: Int(ptr))).takeUnretainedValue()
}
class C {
var cID = 0
func foo() {
print("Instance of C, id = \(cID)")
}
}
class D {
var dID = 0
func foo() {
print("Instance of D, id = \(dID)")
}
}
let c : C = C()
let d : D = D()
c.cID = 123;
d.dID = 321;
let cPtr : Int64 = getPointer(c)
let dPtr : Int64 = getPointer(d)
c.cID *= 10
let c1 : C = recoverObject(cPtr)
let d1 : D = recoverObject(dPtr)
c1.foo()
d1.foo()
The output is:
Instance of C, id = 1230
Instance of D, id = 321
Thanks to user3441734 for some helpful hints! Note the use of generics. The functions for getting a "pointer" and de-referencing it should work with any class (won't work with structs, though).
As far as safer ways of doing this, the answer would depend on the context of what you are doing. Why can't the array of instances be accessed wherever you need the instances instead of obtaining them via Int64s? If the array is actually maintained by (Objective-)C code in a 3rd party library, then there are additional problems that may arise due to memory alignment etc. It may be possible to write C code that would return instances to Swift code in a safer way.
Please let me know about more details if the answer doesn't work for some reason.
class C {
func foo() {
print("C")
}
}
var c = C()
let addr = unsafeAddressOf(c)
dump(addr)
/*
▿ UnsafePointer(0x7F86E942B230)
- pointerValue: 140217415807536
*/
let pC = withUnsafePointer(&c) { (p) -> UnsafePointer<C> in
return p
}
dump(pC)
/*
▿ UnsafePointer(0x10DE5B390)
- pointerValue: 4528124816
*/
dump(pC.memory)
/*
- C #0
*/
let opaquePointer = COpaquePointer(addr)
let unmanagedC = Unmanaged<C>.fromOpaque(opaquePointer)
dump(unmanagedC)
/*
▿ Swift.Unmanaged<C>
- _value: C #0
*/
// I still dont have an idea how to use it ...
ha, i got it!
unmanagedC.takeUnretainedValue().foo() // prints C !

Extending Seq.sortBy in Scala

Say I have a list of names.
case class Name(val first: String, val last: String)
val names = Name("c", "B") :: Name("b", "a") :: Name("a", "B") :: Nil
If I now want to sort that list by last name (and if that is not enough, by first name), it is easily done.
names.sortBy(n => (n.last, n.first))
// List[Name] = List(Name(a,B), Name(c,B), Name(b,a))
But what, if I‘d like to sort this list based on some other collation for strings?
Unfortunately, the following does not work:
val o = new Ordering[String]{ def compare(x: String, y: String) = collator.compare(x, y) }
names.sortBy(n => (n.last, n.first))(o)
// error: type mismatch;
// found : java.lang.Object with Ordering[String]
// required: Ordering[(String, String)]
// names.sortBy(n => (n.last, n.first))(o)
is there any way that allow me to change the ordering without having to write an explicit sortWith method with multiple if–else branches in order to deal with all cases?
Well, this almost does the trick:
names.sorted(o.on((n: Name) => n.last + n.first))
On the other hand, you can do this as well:
implicit val o = new Ordering[String]{ def compare(x: String, y: String) = collator.compare(x, y) }
names.sortBy(n => (n.last, n.first))
This locally defined implicit will take precedence over the one defined on the Ordering object.
One solution is to extend the otherwise implicitly used Tuple2 ordering. Unfortunately, this means writing out Tuple2 in the code.
names.sortBy(n => (n.second, n.first))(Ordering.Tuple2(o, o))
I'm not 100% sure what methods you think collator should have.
But you have the most flexibility if you define the ordering on the case class:
val o = new Ordering[Name]{
def compare(a: Name, b: Name) =
3*math.signum(collator.compare(a.last,b.last)) +
math.signum(collator.compare(a.first,b.first))
}
names.sorted(o)
but you can also provide an implicit conversion from a string ordering to a name ordering:
def ostring2oname(os: Ordering[String]) = new Ordering[Name] {
def compare(a: Name, b: Name) =
3*math.signum(os.compare(a.last,b.last)) + math.signum(os.compare(a.first,b.first))
}
and then you can use any String ordering to sort Names:
def oo = new Ordering[String] {
def compare(x: String, y: String) = x.length compare y.length
}
val morenames = List("rat","fish","octopus")
scala> morenames.sorted(oo)
res1: List[java.lang.String] = List(rat, fish, octopus)
Edit: A handy trick, in case it wasn't apparent, is that if you want to order by N things and you're already using compare, you can just multiply each thing by 3^k (with the first-to-order being multiplied by the largest power of 3) and add.
If your comparisons are very time-consuming, you can easily add a cascading compare:
class CascadeCompare(i: Int) {
def tiebreak(j: => Int) = if (i!=0) i else j
}
implicit def break_ties(i: Int) = new CascadeCompare(i)
and then
def ostring2oname(os: Ordering[String]) = new Ordering[Name] {
def compare(a: Name, b: Name) =
os.compare(a.last,b.last) tiebreak os.compare(a.first,b.first)
}
(just be careful to nest them x tiebreak ( y tiebreak ( z tiebreak w ) ) ) so you don't do the implicit conversion a bunch of times in a row).
(If you really need fast compares, then you should write it all out by hand, or pack the orderings in an array and use a while loop. I'll assume you're not that desperate for performance.)

Resources