I am trying to create a new struct and use its original value as a member of the new struct. However, they both end up being the same reference (i.e. payload and payload.prev) and it causes infinite recursion in my code. I appreciate any help or hint.
package main
type Sieve struct {
prime int
prev *Sieve
}
func Test(payload *Sieve, n int) {
if payload.prime*(n/payload.prime) == n {
} else if payload.prev == nil {
println(n)
// payload and payload.prev end up being the same reference
// and it causes infinite loop
*payload = Sieve{
prime: n,
prev: payload,
}
} else {
Test(payload.prev, n)
}
}
func main() {
var p = Sieve{
prev: nil,
prime: 2,
}
println(2)
for i := 2; i < 10; i++ {
Test(&p, i)
}
}
You want to update the "payload" pointer to point to the address of a new struct. Construct your new struct like this:
payload = &Sieve{
prime: n,
prev: payload,
}
Before overwriting the Sieve struct pointed by payload make a copy of it:
p := *payload
And now you can assign a new Sieve struct value, storing the address of the copy as its prev field:
*payload = Sieve{
prime: n,
prev: &p,
}
With this change, your app runs and properly outputs the primes between 2 and 10 (try it on the Go Playground):
2
3
5
7
With this code below, you are not creating a new instance of Sieve, you are setting the existing instance of Sieve to point to itself:
*payload = Sieve{
prime: n,
prev: payload,
}
If you want to push the payload one level down, you can do this:
p:=*payload
*payload = Sieve {
prime: n,
prev: &p}
This will first assign the contents of payload to p, and then will rewrite payload contents to point to p.
On the other hand, if you want to create a new payload pointing to the old one, use:
payload = Sieve {
prime: n,
prev: payload }
Then you have to return/use this new payload pointer.
I have a vector of strings and I want to extract some data from them and create a structure out of it. It looks something like this:
let mut my_struct = MyStruct::new(0, 0, 0);
let regex1 = Regex::new("...");
let regex2 = Regex::new("...");
for s_iter in my_str_vec.iter() {
if regex1.is_match(s_iter) {
// parsing the value
// .........
let var1 = regex1.captures("....");
// and assign it to to a field of the struct instance
my_struct.field1 = var1;
}
// do the same thing for other fields each step in the loop
// each step only one regex gets triggered
if regex2.is_match(s_iter) {
// parsing the value
// .........
let var2 = regex12.captures("....");
// and assign it to to a field of the struct instance
my_struct.field2 = var2;
}
}
// now "my_struct" is now completely initialized
As you can see, I have to use mut for the structure. Is there any way to do that without mut? I want to be able to initialize the struct all at once, without mut. Or I can consider other options without mut also.
In a purely functional language, you would need to define a recursive function. In Rust, it would look like this:
fn parse(my_str_vec: Vec<&str>) -> MyStruct {
let my_struct = MyStruct::new(0, 0, 0);
let regex1 = Regex::new(...);
let regex2 = Regex::new(...);
fn process_next<I>(regex1: Regex, regex2: Regex, mut str_iter: I, my_struct: MyStruct) -> MyStruct
where I: Iterator, I::Item: AsRef<str>
{
match str_iter.next() {
Some(s_iter) => {
let my_struct = if regex1.is_match(s_iter.as_ref()) {
let var1 = regex1.captures("var1");
MyStruct { field1: var1, ..my_struct }
} else if regex2.is_match(s_iter.as_ref()) {
let var2 = regex2.captures("var2");
MyStruct { field2: var2, ..my_struct }
} else {
my_struct
};
process_next(regex1, regex2, str_iter, my_struct)
}
None => my_struct
}
}
process_next(regex1, regex2, my_str_vec.iter(), my_struct)
}
Note that there's still a mut in this code: we have to define str_iter as mutable, because calling next() requires the receiver to be mutable.
While the inner function is tail recursive, Rust does not guarantee tail calls, so it could crash with a stack overflow if the input is too large. Personally, I'd rather use mut here, as in your original code, especially since mut in Rust implies no aliasing, which eliminates a whole class of potential bugs.
I want to create a byte storage for the following structure and put both variables (tag and i/d) into the storage. Then I want to write the storage into the TcpStream in a single write; due to a bug on the server side, I can't do it with multiple calls.
I need to use a C-style API that involves unions. The total structure size is 12 bytes:
struct element {
int tag;
union {
int i; double d;
} data;
}
How do I do it? Maybe there's a better way of doing it?
Something like this should be a good start.
You need to use the byteorder crate to handle endianness and write bytes to a stream.
The element type can be conveniently represented as enum on the Rust side.
extern crate byteorder;
use std::net::TcpStream;
use byteorder::{ByteOrder, BigEndian, WriteBytesExt};
use std::io::Write;
enum Element {
A(i32),
B(f64)
}
impl Element {
fn write_to_buffer<T: ByteOrder>(&self, buffer: &mut [u8; 12]) {
let mut buffer = &mut buffer[..];
match *self {
Element::A(n) => {
buffer.write_i32::<T>(0).unwrap();
buffer.write_i32::<T>(n).unwrap();
},
Element::B(n) => {
buffer.write_i32::<T>(1).unwrap();
buffer.write_f64::<T>(n).unwrap();
},
}
}
}
fn main() {
let mut stream = TcpStream::connect("127.0.0.1:1234").unwrap();
let mut buffer = [0u8; 12];
let b = Element::B(317.98);
b.write_to_buffer::<BigEndian>(&mut buffer);
stream.write(&buffer).unwrap();
}
I have a static func that creates a dictionary from a bunch of enums in a struct.
It looks like this:
// Struct section starts here
struct Card {
var rank: Rank
var suit: Suit
func simpleDescription() -> String {
return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
}
// Must use static for non-instance methods
static func createDeck() -> [Card] {
var deck = [Card]()
var n = 1
while let rank = Rank.fromRaw(n) {
var m = 1
while let suit = Suit.fromRaw(m) {
deck += Card(rank: rank, suit: suit)
m++
}
n++
}
return deck
}
}
The output is a nice bunch of enums when I call Card.createDeck() that look like this
{(Enum Value), (Enum Value)}
...
Lots of this
...
{(Enum Value), (Enum Value)}
I can even see the wrapped values if I do this:
for n in deck {
println(n)
}
Which nets me lots of this:
_TtV13__lldb_expr_04Card
I can't figure out how to unwrap these enums; please can someone help me?
Thanks
First of all: you have an array of card, not a dictionary.
Second: items in the array are not optionals hence no need to unwrap anything.
In for loop you can access card description:
for n in deck {
println(n.simpleDescription())
}
I'm wondering if I can somehow use an x, y pair as the key to my dictionary
let activeSquares = Dictionary <(x: Int, y: Int), SKShapeNode>()
But I get the error:
Cannot convert the expression's type '<<error type>>' to type '$T1'
and the error:
Type '(x: Int, y: Int)?' does not conform to protocol 'Hashable'
So.. how can we make it conform?
The definition for Dictionary is struct Dictionary<KeyType : Hashable, ValueType> : ..., i.e. the type of the key must conform to the protocol Hashable. But the language guide tells us that protocols can be adopted by classes, structs and enums, i.e. not by tuples. Therefore, tuples cannot be used as Dictionary keys.
A workaround would be defining a hashable struct type containing two Ints (or whatever you want to put in your tuple).
As mentioned in the answer above, it is not possible. But you can wrap tuple into generic structure with Hashable protocol as a workaround:
struct Two<T:Hashable,U:Hashable> : Hashable {
let values : (T, U)
var hashValue : Int {
get {
let (a,b) = values
return a.hashValue &* 31 &+ b.hashValue
}
}
}
// comparison function for conforming to Equatable protocol
func ==<T:Hashable,U:Hashable>(lhs: Two<T,U>, rhs: Two<T,U>) -> Bool {
return lhs.values == rhs.values
}
// usage:
let pair = Two(values:("C","D"))
var pairMap = Dictionary<Two<String,String>,String>()
pairMap[pair] = "A"
Unfortunately, as of Swift 4.2 the standard library still doesn't provide conditional conformance to Hashable for tuples and this is not considered valid code by the compiler:
extension (T1, T2): Hashable where T1: Hashable, T2: Hashable {
// potential generic `Hashable` implementation here..
}
In addition, structs, classes and enums having tuples as their fields won't get Hashable automatically synthesized.
While other answers suggested using arrays instead of tuples, this would cause inefficiencies. A tuple is a very simple structure that can be easily optimized due to the fact that the number and types of elements is known at compile-time. An Array instance almost always preallocates more contiguous memory to accommodate for potential elements to be added. Besides, using Array type forces you to either make item types the same or to use type erasure. That is, if you don't care about inefficiency (Int, Int) could be stored in [Int], but (String, Int) would need something like [Any].
The workaround that I found relies on the fact that Hashable does synthesize automatically for fields stored separately, so this code works even without manually adding Hashable and Equatable implementations like in Marek Gregor's answer:
struct Pair<T: Hashable, U: Hashable>: Hashable {
let first: T
let second: U
}
No need special code or magic numbers to implement Hashable
Hashable in Swift 4.2:
struct PairKey: Hashable {
let first: UInt
let second: UInt
func hash(into hasher: inout Hasher) {
hasher.combine(self.first)
hasher.combine(self.second)
}
static func ==(lhs: PairKey, rhs: PairKey) -> Bool {
return lhs.first == rhs.first && lhs.second == rhs.second
}
}
More info: https://nshipster.com/hashable/
I created this code in an app:
struct Point2D: Hashable{
var x : CGFloat = 0.0
var y : CGFloat = 0.0
var hashValue: Int {
return "(\(x),\(y))".hashValue
}
static func == (lhs: Point2D, rhs: Point2D) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
}
struct Point3D: Hashable{
var x : CGFloat = 0.0
var y : CGFloat = 0.0
var z : CGFloat = 0.0
var hashValue: Int {
return "(\(x),\(y),\(z))".hashValue
}
static func == (lhs: Point3D, rhs: Point3D) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z
}
}
var map : [Point2D : Point3D] = [:]
map.updateValue(Point3D(x: 10.0, y: 20.0,z:0), forKey: Point2D(x: 10.0,
y: 20.0))
let p = map[Point2D(x: 10.0, y: 20.0)]!
If you don't mind a bit of inefficiency, you can easily convert your tuple to a string and then use that for the dictionary key...
var dict = Dictionary<String, SKShapeNode>()
let tup = (3,4)
let key:String = "\(tup)"
dict[key] = ...
You can't yet in Swift 5.3.2, But you can use an Array instead of tuple:
var dictionary: Dictionary<[Int], Any> = [:]
And usage is simple:
dictionary[[1,2]] = "hi"
dictionary[[2,2]] = "bye"
Also it supports any dimentions:
dictionary[[1,2,3,4,5,6]] = "Interstellar"
I suggest to implement structure and use solution similar to boost::hash_combine.
Here is what I use:
struct Point2: Hashable {
var x:Double
var y:Double
public var hashValue: Int {
var seed = UInt(0)
hash_combine(seed: &seed, value: UInt(bitPattern: x.hashValue))
hash_combine(seed: &seed, value: UInt(bitPattern: y.hashValue))
return Int(bitPattern: seed)
}
static func ==(lhs: Point2, rhs: Point2) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
}
func hash_combine(seed: inout UInt, value: UInt) {
let tmp = value &+ 0x9e3779b97f4a7c15 &+ (seed << 6) &+ (seed >> 2)
seed ^= tmp
}
It's much faster then using string for hash value.
If you want to know more about magic number.
Add extension file to project (View on gist.github.com):
extension Dictionary where Key == Int64, Value == SKNode {
func int64key(_ key: (Int32, Int32)) -> Int64 {
return (Int64(key.0) << 32) | Int64(key.1)
}
subscript(_ key: (Int32, Int32)) -> SKNode? {
get {
return self[int64key(key)]
}
set(newValue) {
self[int64key(key)] = newValue
}
}
}
Declaration:
var dictionary: [Int64 : SKNode] = [:]
Use:
var dictionary: [Int64 : SKNode] = [:]
dictionary[(0,1)] = SKNode()
dictionary[(1,0)] = SKNode()
Or just use Arrays instead. I was trying to do the following code:
let parsed:Dictionary<(Duration, Duration), [ValveSpan]> = Dictionary(grouping: cut) { span in (span.begin, span.end) }
Which led me to this post. After reading through these and being disappointed (because if they can synthesize Equatable and Hashable by just adopting the protocol without doing anything, they should be able to do it for tuples, no?), I suddenly realized, just use Arrays then. No clue how efficient it is, but this change works just fine:
let parsed:Dictionary<[Duration], [ValveSpan]> = Dictionary(grouping: cut) { span in [span.begin, span.end] }
My more general question becomes "so why aren't tuples first class structs like arrays are then? Python pulled it off (duck and run)."
struct Pair<T:Hashable> : Hashable {
let values : (T, T)
init(_ a: T, _ b: T) {
values = (a, b)
}
static func == (lhs: Pair<T>, rhs: Pair<T>) -> Bool {
return lhs.values == rhs.values
}
func hash(into hasher: inout Hasher) {
let (a, b) = values
hasher.combine(a)
hasher.combine(b)
}
}
let myPair = Pair(3, 4)
let myPairs: Set<Pair<Int>> = set()
myPairs.update(myPair)