In NodeJS, when we want to declare some constant variable and would like them to be used across the project, we might write something like:
// const.js
module.exports.mqttQOS = {
AtMostOnce: 0,
AtLeastOnce: 1,
ExactlyOnce: 2,
};
Therefore, we could use it like constant.mqttQOS.AtMostOnce, and throw an error when we use constantQOS.ErrorRefering.
In Golang we could only do something like:
var mqttQoS = map[string]byte{
"AtMostOnce": 0,
"AtLeastOnce": 1,
"ExactlyOnce": 2,
}
And use it as: fmt.Println(mqttQoS["AtMostOnce"]) // print: 0
However, it'll print fmt.Println(mqttQoS["ErrorRefering"]) // print: 0 because of the characteristic of Golang map (like Python's defaultdict() )
Althought we could do something to prevent this error referring by:
var mqttQoS = map[string]byte{
"AtMostOnce": 0,
"AtLeastOnce": 1,
"ExactlyOnce": 2,
}
result, ok := mqttQoS["ErrorRefering"]
if ok {
fmt.Println("value: ", result)
}
So back to my question, other than using ok to limit the error referring,
is there any better practice to work on the nested constant objects in Golang?
Updated:
so that I could use like mqttQoS.AtMostOnce and will raise an error when I mqttQos.ErrorRefer.
Defining another type is one way, but is it common practice in big projects?
Thanks!
Referred to the comments, using nested const is not the common practice in Golang.
constant literal might be the solution to the question.
There are related discussions and proposals on github.com/golang
https://github.com/golang/go/issues/21130
Related
I frequently use the following pattern to create objects with null/undefined properties omitted:
const whatever = {
something: true,
...(a ? { a } : null),
...(b ? { b } : null),
};
As of flow release v0.112, this leads to the error message:
Computing object literal [1] may lead to an exponentially large number of cases to reason about because conditional [2] and conditional [3] are both unions. Please use at most one union type per spread to simplify reasoning about the spread result. You may be able to get rid of a union by specifying a more general type that captures all of the branches of the union.
It sounds to me like this isn't really a type error, just that Flow is trying to avoid some heavier computation. This has led to dozens of flow errors in my project that I need to address somehow. Is there some elegant way to provide better type information for these? I'd prefer not to modify the logic of the code, I believe that it works the way that I need it to (unless someone has a more elegant solution here as well). Asking here before I resort to // $FlowFixMe for all of these.
Complete example on Try Flow
It's not as elegant to write, and I think Flow should handle the case that you've shown, but if you still want Flow to type check it you could try rewriting it like this:
/* #flow */
type A = {
cat: number,
};
type B = {
dog: string,
}
type Built = {
something: boolean,
a?: A,
b?: B,
};
function buildObj(a?: ?A, b?: ?B): Built {
const ret: Built = {
something: true
};
if(a) ret.a = a
if(b) ret.b = b
return ret;
}
Try Flow
I would like to compute the phase of a complex number using boost::compute
here is my attempt, I expect the result to be equal to atan2(0.5f):
namespace bc = boost::compute;
bc::vector<std::complex<float>> vec{ {1.0f, 2.0f} };
bc::vector<float> result(1);
bc::transform(vec.begin(), vec.end(), result.begin(), bc::atan2<float>());
but I get a compilation error claiming "Non-unary function invoked one argument"
boost::compute's atan2 would appear to be a binary function just like std::atan2.
I'm assuming you're trying to obtain the phase angle of your complex number? The standard C++ function for this would be std::arg() - I don't see this one being defined in boost::compute, though I might have missed it.
If arg() is indeed missing, you're quite right it's implemented via atan2 - you'll need to extract the imaginary (boost::compute::imag()) and real (boost::compute::real()) components first though, and pass them as individual arguments to atan2.
I think you can also use Boost.Compute's lambda expressions for this:
bc::vector<float2> input{ {1.0f, 2.0f}, {3.0f, 4.0f}, {5.0f, 6.0f} };
bc::vector<float> output(3);
using boost::compute::lambda::atan2;
using boost::compute::_1;
using boost::compute::lambda::get;
bc::transform(
float2_input.begin(),
float2_input.end(),
float_output.begin(),
atan2(get<1>(_1), get<0>(_1)),
queue
);
float2 is bassically a complex in Boost.Compute. You can also check test_lambda.cpp.
I found a way to make it work.
stage 1: allocate 2 vectors:
bc::vector<std::complex<float>> vec{ {1.0f, 2.0f}, {3.0f, 4.0f}, {5.0f, 6.0f} };
bc::vector<float> result(3);
stage 2: interpret the complex vector as a float buffer iterator
buffer_iterator is quite useful when you have a strongly typed vector and would like to pass it to an algorithm as a different type.
auto beginf = bc::make_buffer_iterator<float>(vec.get_buffer(), 0);
auto endf = bc::make_buffer_iterator<float>(vec.get_buffer(), 6); // note end point to final index + 1
stage 3: define strided iterators so that we can use the same buffer as the argument for tan2. each iterator iterates the buffers in strides of 2 indices, and they supply tan2 with interleaved access to the buffer:
auto begin_a = bc::make_strided_iterator(beginf + 1, 2); // access imaginary part
auto end_a = bc::make_strided_iterator_end(beginf + 1, endf , 2);
auto begin_b = bc::make_strided_iterator(beginf, 2); // access real part
finally, call transform:
bc::transform(begin_a, end_a, begin_b, result.begin(), bc::atan2<float>()); // atan(b/a)
bc::system::default_queue().finish();
declare variable $testseq as item()* := ();
declare function local:insertseq($target as item()*, $position as xs:integer?, $inserts as item()*)
as item()* (:might be great if we have a keyword to represent nothing:)
{
fn:insert-before($target, 1, $inserts) (:change the global sequence:)
() (:simulate returning nothing, empty sequence:)
};
element test
{
attribute haha {"&"},
local:insertseq($testseq, 1, ('a', 'b')),
$testseq
}
I need to collect something into a global sequence while the script running. At the end of the script I release the sequence. The function insertseq must return nothing. It is possible with XQuery? Or are there other tricks to do it?
Error from BaseX:
$ basex test.xqy
Stopped at /Users/jack/Documents/SHK/XSD2OWL/Workspace/xqy/test.xqy, 7/4:
[XPTY0004] Item expected, sequence found: ("a", "b").
The answer on the title of your original question would actually be:
declare function local:f() as empty-sequence() {
()
};
As you probably want to solve a specific problem, you could think about creating a new question with another title and a corresponding problem description (including a tiny example with the expected input and output).
In functional languages, such as XQuery, variables cannot be reassigned once they have been defined (see Referential Transparency). As a consequence, you’ll need to use recursive functions to repeatedly add values to a sequence. fn:fold-left can be used as well: it feels challenging when being used for the first time, but once you understand what it does, you don’t want to miss is.
I was learning golang, and as I was going through the chapter that describes Structures, I came across different ways to initialize structures.
p1 := passport{}
var p2 passport
p3 := passport{
Photo: make([]byte, 0, 0),
Name: "Scott",
Surname: "Adam",
DateOfBirth: "Some time",
}
fmt.Printf("%s\n%s\n%s\n", p1, p2, p3)
While these print the values of the structures as
{ }
{ }
{ Scott Adam Some time}
, the following code below prints with an ampersand because it is a reference.
pointerp1 := &p3
fmt.Printf("%s", pointerp1)
pointerp2 := new(passport)
pointerp2.Name = "Anotherscott"
fmt.Printf("%s", pointerp2)
&{ Scott Adam Some time}&{ Anotherscott }
Kindly help me with my doubts.
in the usage pointerp1 := &p3, pointerp1 is the reference variable to p3, which holds the actual data. Similarly, what would be the actual variable that holds the data for pointerp2?
What would be the best scenarios to use these different types of initialization?
new allocates zeroed storage for a new item or type whatever and then returns a pointer to it. I don't think it really matters on if you use new vs short variable declaration := type{} it's mostly just preference
As for pointer2, the pointer2 variable holds its own data, when you do
// initializing a zeroed 'passport in memory'
pointerp2 := new(passport)
// setting the field Name to whatever
pointerp2.Name = "Anotherscott"
new allocates zeroed storage in memory and returns a pointer to it, so in short, new will return a pointer to whatever you're making that is why pointerp2 returns &{ Anotherscott }
You mainly want to use pointers when you're passing a variable around that you need to modify (but be careful of data races use mutexes or channels If you need to read and write to a variable from different functions)
A common method people use instead of new is just short dec a pointer type:
blah := &passport{}
blah is now a pointer to type passport
You can see in this playground:
http://play.golang.org/p/9OuM2Kqncq
When passing a pointer, you can modify the original value. When passing a non pointer you can't modify it. That is because in go variables are passed as a copy. So in the iDontTakeAPointer function it is receiving a copy of the tester struct then modifying the name field and then returning, which does nothing for us as it is modifying the copy and not the original.
There is variable that holds the data yet. You can dereference the pointer using *pointerp2, and even assign it that to a variable (p2 := pointerp2), but this variable would be a copy of the data. That is, modifying one no longer affects the other (http://play.golang.org/p/9yRYbyvG8q).
new tends to be less popular, especially with regard to structs. A good discussion of its purpose (hint: it came first) and use cases can be found at https://softwareengineering.stackexchange.com/a/216582.
Edit: Also, p1 is not really a different kind of initialization from p3, but instead of assigning a value to any of the type's fields they are initialized to their zero value ("" for string, nil for []byte). The same would happen for any omitted fields:
p4 := passport{
Name: "Scott",
Surname: "Adam",
}
In this case, p4.Photo and p4.DateOfBirth would still be zero-valued (nil and "" respectively). The passport{} case it just one where all the fields are omitted.
All the new keyword does is basically create a instance of the type you want. However instead of returning the plain declaration of the type, it references it and return the acutal memory address of that type in the program process heap.
I was experiencing strange phenomena in golang where my pointer declared as myptr:= new(ptrtype)
was resulting in false from if myptr==nil, so I went ahead and tried defining it as myptr:=&ptrtype{} and still didn't work. So then I just defined the pointer with new() and then i set it = nill and now it works. don't know why I didn't have to do that with the other ones.
I'm writing an application in Flex / ActionScript and have a number of class member variables of type Array storing data.
My question is: what's the "best" way to clear out an Array object?
I noticed the ArrayCollection class has a function removeAll() which does this, but the basic Array class does not. Some possibilities I've considered are:
Iterating through the array, calling pop or shift on each element
Setting the array length to 0
Setting the member variable to a "new Array()" or "[]"
I'd say:
myArray = [ ];
That's explicit, short, and makes good use of the VM's garbage collector.
Your first alternative runs a lot of interpreted code to get the same result.
I don't know that the second does what you want; if it does, it's hacky, unclear.
The "new Array()" variant of the third alternative is just wordy, offering no advantage over an array literal. If you also write JS and use JSLint, you'll get yelled at for not using the array literal form.
I'm afraid to say but Warren Young is wrong when he said that setting the myArray = [] cause the garbage collector to pick up the array.
as you have the ability to add a reference to itself within itself, and therefore would never be collected and using up memory, especially if the array has some Sprites in the array, as they too would have the array references them and they too would never be collected.
Sly_cardinal and Richard Szalay are 100% correct. but the length parameter is not needed in Richard's.
To totally clear the array and make sure its collected by garbage then
myArray.splice(0);
myArray = null;
It depends on your context. While using Mr. Young's answer is often the most correct way to do things, it will not always work, especially if you have two variables pointing to the same array:
var foo:Array
var bar:Array
foo = bar = [ 1, 2, 3 ];
bar = [];
trace( foo ); // 1,2,3
On the other hand, if you actually empty the array manually:
var foo:Array
var bar:Array
foo = bar = [ 1, 2, 3 ];
var l:int = bar.length; // get the length FIRST!
// Otherwise bar.length will change
// while you iterate!
for( var i:int = 0; i < l; i++ )
{
bar.shift();
}
trace( foo ); // does not trace anything
If you can modify the array reference, then I would go with Warren's answer. If you need to modify the existing instance, you can also use Array.splice:
var arr : Array = [1, 2, 3, 4, 5];
arr.splice(0, arr.length);
According to this test the best way is to set length = 0