Why is my setter not working on an anonymous struct field? - struct

I'm just learning Go, and here's some behaviour I can't quite get my head around:
package main
import "fmt"
type Message interface {
SetSender(sender string)
}
type message struct {
sender string
}
type Join struct {
message
Channel string
}
func (m message) SetSender(sender string) {
m.sender = sender
}
func main() {
var msg Message
msg = Join{}
msg.SetSender("Jim")
fmt.Printf("%s", msg)
}
This prints {{} }, so the SetSender call doesn't seem to take effect. I suspect that it is somehow operating on a copy of the message, but I can't figure out where such a copy would come from. I tried changing SetSender to operate on *message but that won't compile.
Playground: http://play.golang.org/p/yNdnM1bfSG
Suggestions for alternative design patterns are also welcome. I have several types of messages (only Join is shown here), but they all have some fields in common (only sender is shown here). I'd like to avoid having to write and export a separate constructor for each message type, so it would be great if I can just keep exporting the types themselves.

You should use pointer to message, not a message.
func (m *message) SetSender(sender string) {
m.sender = sender
}
func main() {
var msg Message
msg = new(Join)
msg.SetSender("Jim")
fmt.Printf("%s", msg)
}
It will change the structure. Function on message changes copy of the object, function on pointer to message changes the object.
http://golangtutorials.blogspot.com/2011/06/methods-on-structs.html

Related

How to chan "RoomDatabase and Retrofit" in RxJava

I'm using the Repository Pattern.
I would like to implement logic that if there is no value in the internal DB returns the value of the Api Response and inserts it in the internal DB.
Received internal DB Value (Single Type) Return final value if found, Request Server Api if not found Insert in internal DB (Completable Type) Return final value (Single Type)
If any of these processes call onError, the final return value of this logic shall be onError.
fun getAllStudent(): Single<List<StudentEntity>> =
cache.getAllStudent().onErrorResumeNext { getAllStudentRemote() }
private fun getAllStudentRemote(): Single<List<StudentEntity>> =
remote.getAllMember()
.map { memberData -> memberData.students }
.map { studentList -> studentList.map { student -> studentMapper.mapToEntity(student) } }
.doOnSuccess { studentEntityList -> cache.insertStudents(studentEntityList) }
This is how I tried.
However, in the insert section, because it cannot subscribe, It cannot insert into internal DB or detect onError.
How can I implement this logic? ++ I'm sorry for my poor English.
Since you need to wait for cache.insertStudents() to complete, one thing you can do is to chain cache.insertStudents() into the stream using flatMap.
For example:
fun getAllStudent(): Single<List<StudentEntity>> =
cache.getAllStudent().onErrorResumeNext { getAllStudentRemote() }
private fun getAllStudentRemote(): Single<List<StudentEntity>> =
remote.getAllMember()
.map { memberData -> memberData.students }
.map { studentList -> studentList.map { student -> studentMapper.mapToEntity(student) } }
.flatMap { studentEntityList ->
cache.insertStudents(studentEntityList) // Completable
.toSingleDefualt(studentEntityList) // Convert to Single<List<StudentEntity>>
}
Also note that .do... operators are side-effect operators, and you should not do any operation that can affect the stream.

Use a Queue to Communicate Between Threads in D

It is easy enough in D to create a Queue type using the std.container.dlist.
I would like to have multiple threads but have them communicate with a queue, not with message passing (https://tour.dlang.org/tour/en/multithreading/message-passing). As I understand it the messages are designed to always receive data at particular points in the code; the receiving thread will block until the expected data is received.
(EDIT: I was informed about receiveTimeout but having a no timeout and just a check is really more appropriate in this case (maybe a timeout of 0?). Also I am not sure what the message API will do if multiple messages are sent before any any are received. I will have to play with that.)
void main() {
spawn(&worker, thisTid);
// This line will block until the expected message is received.
receive (
(string message) {
writeln("Received the message: ", text);
},
)
}
What I am needing is to merely receive data if there is some. Something like this:
void main() {
Queue!string queue// custom `Queue` type based on DList
spawn(&worker, queue);
while (true) {
// Go through any messages (while consuming `queue`)
for (string message; queue) {
writeln("Received a message: ", text);
}
// Do other stuff
}
}
I have tried using shared variables (https://tour.dlang.org/tour/en/multithreading/synchronization-sharing) but DMD is complaining that "Aliases to mutable thread-local data not allowed." or some other errors, depending.
How would this be done in D? Or, is there a way to use messages to do this kind of communication?
This doesn't answer the specific question but ti does clear up what I think is a misunderstanding of the message passing api...
just call receiveTimeout instead of plain receive
http://dpldocs.info/experimental-docs/std.concurrency.receiveTimeout.html
I use this:
shared class Queue(T) {
private T[] queue;
synchronized void opOpAssign(string op)(T object) if(op == "~") {
queue ~= object;
}
synchronized size_t length(){
return queue.length;
}
synchronized T pop(){
assert(queue.length, "Please check queue length, is 0");
auto first = queue[0];
queue = queue[1..$];
return first;
}
synchronized shared(T[]) consume(){
auto copy = queue;
queue = [];
return copy;
}
}
I have gotten the answer I need.
Simply put, use core.thread rather than std.concurrency. std.concurrency manages messages for you and does not allow you to manage it yourself. core.thread is what std.concurrency uses internally.
The longer answer, here is how I fully implemented it.
I have created a Queue type that is based on an Singly Linked List but maintains a pointer of the last element. The Queue also uses standard component inputRange and outputRange (or at least I think it does) per Walter Brights vision (https://www.youtube.com/watch?v=cQkBOCo8UrE).
The Queue is also built to allow one thread to write and another to read with very little mutexing internally so it should be fast.
The Queue I shared here https://pastebin.com/ddyPpLrp
A simple implementation to have a second thread read input:
Queue!string inputQueue = new Queue!string;
ThreadInput threadInput = new ThreadInput(inputQueue);
threadInput.start;
while (true) {
foreach (string value; inputQueue) {
writeln(value);
}
}
ThreadInput being defined as thus:
class ThreadInput : Thread {
private Queue!string queue;
this(Queue!string queue) {
super(&run);
this.queue = queue;
}
private void run() {
while (true) {
queue.put(readln);
}
}
}
The code https://pastebin.com/w5jwRVrL
The Queue again https://pastebin.com/ddyPpLrp

Automatic Type Assertion In Go

Take this sample of code (playground):
package main
import (
"fmt"
)
type Foo struct {
Name string
}
var data = make(map[string]interface{})
func main() {
data["foo"] = &Foo{"John"}
foo := data["foo"].(*Foo)
fmt.Println(foo.Name)
}
When I add something to data, the type turns into an interface{}, so when I later retrieve that value I have to assert the original type back onto it. Is there a way to, for example, define a getter function for data which will automagically assert the type?
Not really, unless you turn to reflect and try to get the type of the interface that way.
But the idiomatic (and faster) way remains the type assertion (a "type conversion" which must be checked at runtime, since data only contains interface{} values).
If data were to reference a specific interface (instead of the generic interface{} one), like I mentioned here, then you could use a Name() method defined directly on it.
You can do something like this, but you might want to think about your design.. It is very rare that you need to do this kind of things.
http://play.golang.org/p/qPSxRoozaM
package main
import (
"fmt"
)
type GenericMap map[string]interface{}
func (gm GenericMap) GetString(key string) string {
return gm[key].(string)
}
func (gm GenericMap) GetFoo(key string) *Foo {
return gm[key].(*Foo)
}
func (gm GenericMap) GetInt(key string) int {
return gm[key].(int)
}
var data = make(GenericMap)
type Foo struct {
Name string
}
func main() {
data["foo"] = &Foo{"John"}
foo := data.GetFoo("foo")
fmt.Println(foo.Name)
}
You might want to add error checking, in case the key does not exists or is not the expected type.

Mutating in Structure Swift Same function Name

Still trying out swift, and I came across this problem (not sure if it really classifies as one)
So we have a protocol, and a structure that inherits it.
protocol ExampleProtocol {
var simpleDescription: String { get }
func adjust()
}
struct SimpleStructure : ExampleProtocol{
var simpleDescription = "A simple structure"
mutating func adjust() {
simpleDescription += " (adjusted)"
}
func adjust() { //I created this second method just to conform to the protocol
}
}
var b = SimpleStructure()
b.adjust() //This generates a compiler error mentioning Ambiguity (Correct)
Question is how do I call the mutating adjust() not the adjust from the protocol. i.e. I know if I declare b as a protocol and initialized it to the struct it will call adjust from protocol, but how do I call the first adjust ? or is it not possible? Or Am I using it wrongly ?
Cheers,
Your code doesn't compile, but the error is in redefining the adjust method by adding the mutating attribute - that doesn't create an overloaded version of adjust.
In my opinion this is the correct code:
protocol ExampleProtocol {
var simpleDescription: String { get }
mutating func adjust()
}
struct SimpleStructure : ExampleProtocol{
var simpleDescription = "A simple structure"
mutating func adjust() {
simpleDescription += " (adjusted)"
}
}
which means: you have to define the adjust function as mutating in the protocol.

Is there a way to cast Structs for sending over a channel

In GOLANG is there an easy to way to cast structs for polymorphic behavior across channels? I'm trying to send different versions of a struct across one channel, so for example I'm going to have different types of Events, like a LoginEvent. Each one will have different amounts of data in the struct.
package main
import "fmt"
type Event struct {
EvtType EvtType
Username string
Data string
}
type LoginEvent struct {
Event
CallBackChannel chan *Event
}
type EvtType int
const (
Login EvtType = iota+1
Logout
ChatMessage
Presense
BuddyList
)
func main() {
fakeOutputChan := make(chan<- *Event)
ourSrvChannel := make(chan *Event)
lg := (LoginEvent{Event{Login,"",""} ,ourSrvChannel})
fakeOutputChan <- (*Event)(&lg)
fmt.Println("Hello, playground")
}
The idiomatic way to do is, is to use interfaces and then do a type assertion on the receiving end. Your Event struct should ideally be an interface.
type Event interface {
// Methods defining data all events share.
}
type UserEvent struct {
Name string
}
// Define methods on *UserEvent to have it qualify as Event interface.
type LoginEvent struct {
...
}
// Define methods on *LoginEvent to have it qualify as Event interface.
Then you can define your channel to accept anything that qualifies as the Event interface.
ch := make(chan Event)
The receiving end will receive the Event objects and can do a type assertion to see what
concrete type underlies it:
select {
case evt := <- ch:
if evt == nil {
return
}
switch evt.(type) {
case *LoginEvent:
case *UserEvent:
....
}
}

Resources