• Guest
HabraHabr
  • Main
  • Users

  • Development
    • Programming
    • Information Security
    • Website development
    • JavaScript
    • Game development
    • Open source
    • Developed for Android
    • Machine learning
    • Abnormal programming
    • Java
    • Python
    • Development of mobile applications
    • Analysis and design of systems
    • .NET
    • Mathematics
    • Algorithms
    • C#
    • System Programming
    • C++
    • C
    • Go
    • PHP
    • Reverse engineering
    • Assembler
    • Development under Linux
    • Big Data
    • Rust
    • Cryptography
    • Entertaining problems
    • Testing of IT systems
    • Testing Web Services
    • HTML
    • Programming microcontrollers
    • API
    • High performance
    • Developed for iOS
    • CSS
    • Industrial Programming
    • Development under Windows
    • Image processing
    • Compilers
    • FPGA
    • Professional literature
    • OpenStreetMap
    • Google Chrome
    • Data Mining
    • PostgreSQL
    • Development of robotics
    • Visualization of data
    • Angular
    • ReactJS
    • Search technologies
    • Debugging
    • Test mobile applications
    • Browsers
    • Designing and refactoring
    • IT Standards
    • Solidity
    • Node.JS
    • Git
    • LaTeX
    • SQL
    • Haskell
    • Unreal Engine
    • Unity3D
    • Development for the Internet of things
    • Functional Programming
    • Amazon Web Services
    • Google Cloud Platform
    • Development under AR and VR
    • Assembly systems
    • Version control systems
    • Kotlin
    • R
    • CAD/CAM
    • Customer Optimization
    • Development of communication systems
    • Microsoft Azure
    • Perfect code
    • Atlassian
    • Visual Studio
    • NoSQL
    • Yii
    • Mono и Moonlight
    • Parallel Programming
    • Asterisk
    • Yandex API
    • WordPress
    • Sports programming
    • Lua
    • Microsoft SQL Server
    • Payment systems
    • TypeScript
    • Scala
    • Google API
    • Development of data transmission systems
    • XML
    • Regular expressions
    • Development under Tizen
    • Swift
    • MySQL
    • Geoinformation services
    • Global Positioning Systems
    • Qt
    • Dart
    • Django
    • Development for Office 365
    • Erlang/OTP
    • GPGPU
    • Eclipse
    • Maps API
    • Testing games
    • Browser Extensions
    • 1C-Bitrix
    • Development under e-commerce
    • Xamarin
    • Xcode
    • Development under Windows Phone
    • Semantics
    • CMS
    • VueJS
    • GitHub
    • Open data
    • Sphinx
    • Ruby on Rails
    • Ruby
    • Symfony
    • Drupal
    • Messaging Systems
    • CTF
    • SaaS / S+S
    • SharePoint
    • jQuery
    • Puppet
    • Firefox
    • Elm
    • MODX
    • Billing systems
    • Graphical shells
    • Kodobred
    • MongoDB
    • SCADA
    • Hadoop
    • Gradle
    • Clojure
    • F#
    • CoffeeScript
    • Matlab
    • Phalcon
    • Development under Sailfish OS
    • Magento
    • Elixir/Phoenix
    • Microsoft Edge
    • Layout of letters
    • Development for OS X
    • Forth
    • Smalltalk
    • Julia
    • Laravel
    • WebGL
    • Meteor.JS
    • Firebird/Interbase
    • SQLite
    • D
    • Mesh-networks
    • I2P
    • Derby.js
    • Emacs
    • Development under Bada
    • Mercurial
    • UML Design
    • Objective C
    • Fortran
    • Cocoa
    • Cobol
    • Apache Flex
    • Action Script
    • Joomla
    • IIS
    • Twitter API
    • Vkontakte API
    • Facebook API
    • Microsoft Access
    • PDF
    • Prolog
    • GTK+
    • LabVIEW
    • Brainfuck
    • Cubrid
    • Canvas
    • Doctrine ORM
    • Google App Engine
    • Twisted
    • XSLT
    • TDD
    • Small Basic
    • Kohana
    • Development for Java ME
    • LiveStreet
    • MooTools
    • Adobe Flash
    • GreaseMonkey
    • INFOLUST
    • Groovy & Grails
    • Lisp
    • Delphi
    • Zend Framework
    • ExtJS / Sencha Library
    • Internet Explorer
    • CodeIgniter
    • Silverlight
    • Google Web Toolkit
    • CakePHP
    • Safari
    • Opera
    • Microformats
    • Ajax
    • VIM
  • Administration
    • System administration
    • IT Infrastructure
    • *nix
    • Network technologies
    • DevOps
    • Server Administration
    • Cloud computing
    • Configuring Linux
    • Wireless technologies
    • Virtualization
    • Hosting
    • Data storage
    • Decentralized networks
    • Database Administration
    • Data Warehousing
    • Communication standards
    • PowerShell
    • Backup
    • Cisco
    • Nginx
    • Antivirus protection
    • DNS
    • Server Optimization
    • Data recovery
    • Apache
    • Spam and antispam
    • Data Compression
    • SAN
    • IPv6
    • Fidonet
    • IPTV
    • Shells
    • Administering domain names
  • Design
    • Interfaces
    • Web design
    • Working with sound
    • Usability
    • Graphic design
    • Design Games
    • Mobile App Design
    • Working with 3D-graphics
    • Typography
    • Working with video
    • Work with vector graphics
    • Accessibility
    • Prototyping
    • CGI (graphics)
    • Computer Animation
    • Working with icons
  • Control
    • Careers in the IT industry
    • Project management
    • Development Management
    • Personnel Management
    • Product Management
    • Start-up development
    • Managing the community
    • Service Desk
    • GTD
    • IT Terminology
    • Agile
    • Business Models
    • Legislation and IT-business
    • Sales management
    • CRM-systems
    • Product localization
    • ECM / EDS
    • Freelance
    • Venture investments
    • ERP-systems
    • Help Desk Software
    • Media management
    • Patenting
    • E-commerce management
    • Creative Commons
  • Marketing
    • Conferences
    • Promotion of games
    • Internet Marketing
    • Search Engine Optimization
    • Web Analytics
    • Monetize Web services
    • Content marketing
    • Monetization of IT systems
    • Monetize mobile apps
    • Mobile App Analytics
    • Growth Hacking
    • Branding
    • Monetize Games
    • Display ads
    • Contextual advertising
    • Increase Conversion Rate
  • Sundry
    • Reading room
    • Educational process in IT
    • Research and forecasts in IT
    • Finance in IT
    • Hakatonas
    • IT emigration
    • Education abroad
    • Lumber room
    • I'm on my way

Such an exceptional Go

 3r31068. 3r3-31. 3r31054. Recently, drafts of the design of a new error handling in Go 2 were published. It is very pleasing that the language does not stand in one place - it develops and becomes prettier with every year by leaps and bounds. 3r3-1057. 3r3-1055.  3r31068. 3r31054. Only now, while Go 2 can only be seen on the horizon, and it’s very painful and sad to wait. Therefore, we take matters into our own hands. A little code generation, a bit of work with ast, and a flick of the wrist turn into panic, turn into elegant exceptions! 3r3-1057. 3r3-1055.  3r31068.

3r311.
library kodogenerator . And kodogenerators, as everyone knows, carry goodness and grace. Not really, but they are quite popular in the Go world. 3r3-1057. 3r3-1055.  3r31068. 3r31054. We set such kodogenerator on go-raw. He parses it for using the standard module 3r3-31004. go /ast 3r31026. , makes there some 3r340. not
tricky transformations, the result is written next to the file, adding the suffix _jex.go . The resulting files for work want a tiny runtime. 3r3-1057. 3r3-1055.  3r31068. 3r31054. This is exactly the way we add exceptions to Go. 3r3-1057. 3r3-1055.  3r31068.

We use 3r3103. 3r3-1055.  3r31068. 3r31054. We connect the generator to the file, in the header (up to 3r3-31004. Package ) We write 3r3-1055.  3r31068.

    //+ build jex
//go: generate jex
3r3-1027. 3r3-1055.  3r31068. 3r31054. If you now run the command go generate -tags jex , then the utility will be executed. jex 3r31026. . It takes the file name from os.Getenv ("GOFILE") eats it, digests it, and writes r3r31004. {file} _jex.go . The newborn file in the header is already //+ build! jex (tag inverted), so that go build , and in a compartment with it and other commands, like go test or go install take into account only new 3r31044. , correct files. Lepot
3r3-1055.  3r31068. 3r31054. Now dot-import github.com/anjensan/jex . 3r3-1055.  3r31068. Yes, yes, while import through a point is required. In the future it is planned to leave exactly the same. 3r3-1057. 3r3-1055.  3r31068.
    import. "github.com/anjensan/jex"    3r3-1027. 3r3-1055.  3r31068. 3r31054. Great, now you can insert stub function calls to the code 3r3-31004. TRY 3r31026. ,    THROW 3r31026. ,    EX    . The code for all this remains syntactically valid, and even compiles in its raw form (it just does not work), so auto-completion and linters are available, 3r31043. not really 3r31044. swear. The editors would also show documentation for these functions, if only they had it. 3r3-1057. 3r3-1055.  3r31068. 3r31054. We throw an exception    3r3-1055.  3r31068.  
    THROW (errors.New ("error name"))    3r3-1027. 3r3-1055.  3r31068. 3r31054. We catch the exception    3r3-1055.  3r31068.  
    if TRY () {
//some code
} else {
fmt.Println (EX ())
}
3r3-1027. 3r3-1055.  3r31068. 3r31054. An anonymous function is generated under the hood. And in her 3r3-31004. defer
. And in it one more function. And in her 3r3-31004. recover
Well, there is a little more ast-magic to handle return and defer . 3r3-1057. 3r3-1055.  3r31068. 3r31054. And yes, by the way, they are supported! 3r3-1057. 3r3-1055.  3r31068. 3r31054. In addition, there is a special macro variable 3r3-31004. ERR 3r31026. . If you assign an error to it, an exception is thrown out. This makes it easier to call functions that in the old fashion still return error 3r3-1057. 3r3-1055.  3r31068.
    file, ERR: = os.Open (filename)    3r3-1027. 3r3-1055.  3r31068. 3r31054. Additionally, there are a couple of small utility bags 3r3-31004. ex    and    must    but there is nothing to talk about. 3r3-1057. 3r3-1055.  3r31068. 3r3178. Examples 3r3-1039. 3r3-1055.  3r31068. 3r31054. Here is an example of a correct, idiomatic code on Go    3r3-1055.  3r31068.  
    func CopyFile (src, dst string) error {
r, err: = os.Open (src)
if err! = nil {
Return fmt.Errorf ("copy% s% s:% v", src, dst, err)
}
defer r.Close ()
3r31068. w, err: = os.Create (dst)
if err! = nil {
Return fmt.Errorf ("copy% s% s:% v", src, dst, err)
}
3r31068. if _, err: = io.Copy (w, r); err! = nil {
w.Close ()
os.Remove (dst)
Return fmt.Errorf ("copy% s% s:% v", src, dst, err)
}
3r31068. if err: = w.Close (); err! = nil {
os.Remove (dst)
Return fmt.Errorf ("copy% s% s:% v", src, dst, err)
}
}
3r3-1027. 3r3-1055.  3r31068. 3r31054. This code is not so pleasant and elegant. By the way, this is not just my opinion! 3r3-1055.  3r31068. But jex 3r31026. help us improve it 3r3-1055.  3r31068.
    func CopyFile_ (src, dst string) {
defer ex.Logf ("copy% s% s", src, dst)
3r31068. r, ERR: = os.Open (src)
defer r.Close ()
3r31068. w, ERR: = os.Create (dst)
3r31068. if TRY () {
ERR: = io.Copy (w, r)
ERR: = w.Close ()
} else {
w.Close ()
os.Remove (dst)
THROW () 3—3—31068.}
}
3r3-1027. 3r3-1055.  3r31068. 3r31054. But for example the following program 3r31057. 3r3-1055.  3r31068.
    func main () {
hex, err: = ioutil.ReadAll (os.Stdin)
if err! = nil {
log.Fatal (err)
}
3r31068. data, err: = parseHexdump (string (hex))
if err! = nil {
log.Fatal (err)
}
3r31068. os.Stdout.Write (data)
}
3r3-1027. 3r3-1055.  3r31068. 3r31054. can be rewritten as 3r3-1055.  3r31068.
    func main () {
if TRY () {
hex, ERR: = ioutil.ReadAll (os.Stdin)
data, ERR: = parseHexdump (string (hex))
os.Stdout.Write (data)
} else {
log.Fatal (EX ())
}
}
3r3-1027. 3r3-1055.  3r31068. 3r31054. Here is another example in order to feel the proposed idea better. The original code is 3r3-1055.  3r31068.
    func printSum (a, b string) error {
x, err: = strconv.Atoi (a)
if err! = nil {
return err
}
y, err: = strconv.Atoi (b)
if err! = nil {
return err
}
fmt.Println ("result:", x + y)
return nil
}
3r3-1027. 3r3-1055.  3r31068. 3r31054. can be rewritten as 3r3-1055.  3r31068.
    func printSum_ (a, b string) {
x, ERR: = strconv.Atoi (a)
y, ERR: = strconv.Atoi (b)
fmt.Println ("result:", x + y)
}
3r3-1027. 3r3-1055.  3r31068. 3r31054. or so even 3r3-1055.  3r31068.
    func printSum_ (a, b string) {
fmt.Println ("result:", must.Int_ (strconv.Atoi (a)) + must.Int_ (strconv.Atoi (b)))
}
3r3-1027. 3r3-1055.  3r31068. 3r33333. The exception is 3r31039. 3r3-1055.  3r31068. 3r31054. The essence is a simple wrapper over an instance of error 3r3-1057. 3r3-1055.  3r31068.
    type exception struct {3r31068. //original error, no comments
err error
//garbage ^ W-debug information, variables, logs there are
log[]interface {} 3r31068. //all of a sudden we have already handled another error when we threw an exception
suppress[]* exception
}
3r3-1027. 3r3-1055.  3r31068. 3r31054. An important point - the usual panic is not perceived as an exception. So, all standard errors are not exceptions, like 3r3-31004. runtime.TypeAssertionerror
. This is consistent with accepted best practices in Go - if we have, say, a nil-dereference, then we cheerfully and cheerfully drop the whole process. Reliable and predictable. Although not sure, perhaps it is worth reviewing this moment and still catching such errors. Maybe optional? 3r3-1057. 3r3-1055.  3r31068. 3r31054. And here is an example of the exception chain 3r3-1055.  3r31068.
    func one_ () {
THROW (errors.New ("one"))
}
3r31068. func two_ () {
THROW (errors.New ("two")
}
Func three () {
If TRY () {
One_ ()
} Rr3r)

 3r31068. 3r31054. Here we calmly handle the exception one as suddenly bang and an exception is thrown two . So to him in the field suppress 3r31026. the original will be automatically attached. one . Nothing is lost, everything goes to the logs. And therefore, there is no particular need to push the entire chain of errors right into the message text with the help of a very popular pattern fmt.Errorf ("blabla:% v", err) . Although no one, of course, prohibits its use here, if you really want to. 3r3-1057. 3r3-1055.  3r31068.

When they forgot to catch

3r3-1055.  3r31068. 3r31054. Ah, another very important moment. In order to increase readability, there is an additional check: if the function can throw an exception, then its name should end with _ 3r31026. . Consciously crooked name, which prompts the programmer "dear sir, here in your program something can go wrong, if you please be careful and diligent!" 3r3-1057. 3r3-1055.  3r31068. 3r31054. The check is started automatically for transformable files, plus it can still be started manually in the project with the help of the command jex-check . Perhaps it makes sense to run it as part of the build process along with other linters. 3r3-1057. 3r3-1055.  3r31068. 3r31054. The check commentary is disabled. //jex: nocheck . This, by the way, is still the only way to throw exceptions from an anonymous function. 3r3-1057. 3r3-1055.  3r31068. 3r31054. Of course this is not a panacea for all problems. Checker will miss this 3r3-1055.  3r31068.
    func bad_ () {
THROW (errors.New ("ups"))
}
func worse () {
f: = bad_
f () 3r31068.}
3r3-1027. 3r3-1055.  3r31068. 3r31054. On the other hand, it is not much worse than the standard test on 3r3-31004. err declared and not used
which is very easy to get around 3r3-1055.  3r31068.
    func worse () {
a, err: = foo ()
if err! = nil {
return err
}
b, err: = bar ()
//behindthere was a check, and everything is ok ok go vet, how long? 3r31068.}
3r3-1027. 3r3-1055.  3r31068. 3r31054. In general, this question is rather philosophical, what is better to do when you forgot to handle the error - quietly ignore it, or throw out panic By the way, better testing results could be achieved by introducing support for exceptions to the compiler, but this is much beyond the scope of this article . 3r3-1057. 3r3-1055.  3r31068. 3r31054. Some may say that, although this is a wonderful solution, it is no exception, since exceptions now mean a very concrete implementation. Well, because the exception is not attached to the exceptions, or there is a separate linter to check the names of the functions, or that the function may end in 3r30031. _ 3r31026. but do not throw exceptions, or do not have direct support in the syntax, or that it is in fact panic, and panic is not an exception at all, because gladiolus Disputes can be as hot as they are useless and purposeless. Therefore, I will leave them behind the board of the article, and the described solution will continue to call the exceptions indifferently. 3r3-1057. 3r3-1055.  3r31068. 3rr3465. Regarding the structures
3r3-1055.  3r31068. 3r31054. Often, developers, in order to simplify debugging, rivet the constructs to custom implementations of 3r3-31004. error . There are even some popular libraries for this. But, fortunately, with exceptions, no additional actions are needed for this, thanks to one interesting feature of Go - in panic units defer are executed in the stack context of the code that threw the panic. Therefore, here 3r3-1055.  3r31068.
    func foo_ () {
THROW (errors.New ("ups"))
}
3r31068. func bar () {
if TRY () {
foo_ ()
} else {
debug.PrintStack ()
}
}
3r3-1027. 3r3-1055.  3r31068. 3r31054. a full-fledged spectra will be printed, even a little verbose (cut out the file names) 3r31057. 3r3-1055.  3r31068.
    runtime /debug.Stack
runtime /debug.PrintStack
main.bar.func2
github.com/anjensan/jex/runtime.TryCatch.func1
panic
main.foo_
main.bar.func1
github.com/anjensan/jex/runtime.TryCatch
main.bar
main.main 3r31026. 3r3-1027. 3r3-1055.  3r31068. 3r31054. It doesn’t hurt to make your own helper for formatting /printing of the glassboard taking into account surrogate functions, hiding them for readability. I think a good idea, recorded in. 3r3-1057. 3r3-1055.  3r31068. 3r31054. And you can grab the stack and attach it to the exception with ex.Log () . Then such an exception is allowed to be transferred to another city hut - straights are not lost. 3r3-1057. 3r3-1055.  3r31068.
    func foobar_ () {
e: = make (chan error, 1)
go func () {
defer close (e)
if TRY () {
checkZero_ ()
} else {
EX (). Log (debug. Stack ()) //attach the
setpoint. e 3r33535.}
} () 3r31068. ex.Must_ (3r33535.}

 3r31068. 3r33540. Unfortunately, 3r3-1055.  3r31068. 3r31054. Eh of course, where something like this would be better than 3r3-1055.  3r31068.
    try {
throw io.EOF, "some comment"
} catch e {
fmt.Printf ("exception:% v", e)
}
3r3-1027. 3r3-1055.  3r31068. 3r31054. But alas, the Go syntax is not extensible. 3r3-1055.  3r31068.[задумчиво]Although, perhaps, this is still for the better
3r3-1055.  3r31068. 3r31054. In any case, it is necessary to pervert. One alternative idea was to do 3r3-1055.  3r31068.
    TRY; {
THROW (io.EOF, "some comment")
}; CATCH; {
fmt.Printf ("exception:% v", EX)
}
3r3-1027. 3r3-1055.  3r31068. 3r31054. But such a code looks awkward after go fmt . And the compiler swears when it sees return in both branches. From 3r3 to 31004. if-TRY
there is no such problem. 3r3-1057. 3r3-1055.  3r31068. 3r31054. It would be cool to replace the macro ERR 3r31026. on function 3r3-31004. MUST 3r31026. (better just 3r3-31004. must ). In order to write 3r3-1055.  3r31068.
    return MUST (strconv.Atoi (a)) + MUST (strconv.Atoi (b))    3r3-1027. 3r3-1055.  3r31068. 3r31054. In principle, this is still realizable, it is possible, when analyzing ast, to display the type of expressions, for all types of types, to generate a simple wrapper function, such as those declared in the package 3r-31004. must    , and then replace    MUST 3r31026. in the name of the corresponding surrogate function. This is not entirely trivial, but it is absolutely possible  Only now editors /ides will not be able to understand such code. After all, the signature of the stub function is    MUST 3r31026. not expressible within the Go type system. And therefore no autocomplete. 3r3-1057. 3r3-1055.  3r31068. 3r31414. Under the hood    3r3-1055.  3r31068. 3r31054. In all the processed files, a new import    is added. 3r3-1055.  3r31068.  
    import _jex "github.com/anjensan/jex/runtime"    3r3-1027. 3r3-1055.  3r31068. 3r31054. Call    THROW 3r31026. replaced by    panic (_jex.NewException ())    . There is also a replacement 3r3-31004. EX () 3r31026. to the name of a local variable in which the caught exception lies. 3r3-1057. 3r3-1055.  3r31068. 3r31054. But    if TRY () {} else {}    processed a little more complicated. First there is a special treatment for all    return    and    defer    . Then the processed if-a branches are placed in anonymous functions. And then these functions are transferred to    _jex.TryCatch ()    . Here is    3r3-1055.  3r31068.  
    func test (a int) (int, string) {
fmt.Println ("before")
if TRY () {
if a == 0 {
THROW (errors.New ("a == 0"))
}
defer fmt.Printf ("a =% dn", a)
return a + ? "ok"
} else {
fmt.Println ("fail")
}
return ? "hmm"
}
3r3-1027. 3r3-1055.  3r31068. 3r31054. turns into something like this (I removed the comments 3r3-31004. //line
): 3r3-1055.  3r31068.
    func test (a int) (_jex_r0 int, _jex_r1 string) {
var _jex_ret bool
3r31068. fmt.Println ("before")
3r31068. var _jex_md2502 _jex.MultiDefer
defer _jex_md2502.Run ()
3r31068. _jex.TryCatch (func () {
if a == 0 {
panic (_jex.NewException (errors.New ("a == 0"))) r3r31068.}
{
_f, _p? _r : = fmt.Printf, "a =% dn", a
_jex_md2502.Defer (func () {_f (_p? _p1)})
}
_jex_ret, _jex_r? _jex_r1 = 3_3r31068. ok "
return
}, func (_jex_ex _jex.Exception) {
defer _jex.Suppress (_jex_ex) 3r31068. fmt.Println (" fail ") 3r31068.} r3r3r3r3r3r3r.???. if _jex_ret {
return
}
return ? "hmm"
}
3r31026. 3r3-1027. 3r3-1055.  3r31068. 3r31054. A lot, not beautiful, but it works. Well, not all and not always. For example, you cannot do defer-recover inside TRY, since the function call wraps around the extra lambda. 3r3-1057. 3r3-1055.  3r31068. 3r31054. Also, when displaying the ast tree, the option "save comments" is specified. So, in theory, go /printer 3r31026. I have to print them out What he honestly does is really very crooked =) I will not give examples, it’s just crooked. In principle, such a problem is quite solvable if you carefully specify the positions for all ast-nodes (they are now empty), but this is definitely not included in the list of necessary things for the prototype. 3r3-1057. 3r3-1055.  3r31068. 3r33737. We try 3r3-1055.  3r31068. 3r31054. Out of curiosity, wrote a small benchmark . 3r3-1057. 3r3-1055.  3r31068. 3r31054. We have a wooden implementation of qsort, which checks for the presence of duplicates. Found - an error. One version is simply forwarding through return err , another clarifies the error by calling fmt.Errorf . And one uses exceptions. Sort slices of different sizes, or without any duplicates (there is no error, the slice is sorted completely), or with one repetition (the sorting stops approximately halfway through, as can be seen from the timing). 3r3-1057. 3r3-1055.  3r31068. 3r33816. 3r33817. Results [/b] 3r33838.
    ~> cat /proc /cpuinfo | grep 'model name' | head -1
model name: Intel (R) Core (TM) i7-6700K CPU @ ???GHz
~> go version
go version go??? linux /amd64
~> go test -bench =. github.com/anjensan/jex/demo
goos: linux
goarch: amd64
pkg: github.com/anjensan/jex/demo
BenchmarkNoErrors /_____ 10 /exception-??? ns /op
BenchmarkNoErrors /_____ 10 /return_err-??? ns /op
BenchmarkNoErrors /_____ 10 /fmt.errorf-??? ns /op
BenchmarkNoErrors /____ 100 /exception-??? ns /op
BenchmarkNoErrors /____ 100 /return_err-??? ns /op
BenchmarkNoErrors /____ 100 /fmt.errorf-??? ns /op
BenchmarkNoErrors /___ 1000 /exception-??? ns /op
BenchmarkNoErrors /___ 1000 /return_err-??? ns /op
BenchmarkNoErrors /___ 1000 /fmt.errorf-??? ns /op
BenchmarkNoErrors /__ 10000 /exception-??? ns /op
BenchmarkNoErrors /__ 10000 /return_err-??? ns /op
BenchmarkNoErrors /__ 10000 /fmt.errorf-??? ns /op
BenchmarkNoErrors /_100000 /exception-??? ns /op
BenchmarkNoErrors /_100000 /return_err-??? ns /op
BenchmarkNoErrors /_100000 /fmt.errorf-??? ns /op
BenchmarkNoErrors /1000000 /exception-??? ns /op
BenchmarkNoErrors /1000000 /return_err-??? ns /op
BenchmarkNoErrors /1000000 /fmt.errorf-??? ns /op
BenchmarkOneError /_____ 10 /exception-??? ns /op
BenchmarkOneError /_____ 10 /return_err-??? ns /op
BenchmarkOneError /_____ 10 /fmt.errorf-??? ns /op
BenchmarkOneError /____ 100 /exception-??? ns /op 3r31068. BenchmarkOneError /____ 100 /return_err-??? ns /op
BenchmarkOneError /____ 100 /fmt.errorf-??? ns /op
BenchmarkOneError /___ 1000 /exception-??? ns /op
BenchmarkOneError /___ 1000 /return_err-??? ns /op
BenchmarkOneError /___ 1000 /fmt.errorf-??? ns /op
BenchmarkOneError /__ 10000 /exception-??? ns /op
BenchmarkOneError /__ 10000 /return_err-??? ns /op
BenchmarkOneError /__ 10000 /fmt.errorf-??? ns /op
BenchmarkOneError /_100000 /exception-??? ns /op
BenchmarkOneError /_100000 /return_err-??? ns /op
BenchmarkOneError /_100000 /fmt.errorf-??? ns /op
BenchmarkOneError /1000000 /exception-??? ns /op
BenchmarkOneError /1000000 /return_err-??? ns /op
BenchmarkOneError /1000000 /fmt.errorf-??? ns /op
PASS 3r31068. ok github.com/anjensan/jex/demo ???s
3r3-1027.
3r3-1055.  

If the error is not thrown (the code is stable and reinforced concrete), then the varant with the exception forwarding is approximately comparable to 3r3-331004. return err and fmt.Errorf . Sometimes a little faster. But if an error was thrown, exceptions go to second place. But it all depends on the ratio of "useful work /errors" and the depth of the stack. For small slices return err goes into the lead, for medium and large exceptions are already equal with manual forwarding. 3r3-1057. 3r3-1055.  3r31068. 3r31054. In short, if errors occur very rarely - exceptions may even speed up the code a bit. If like everyone else, it will be something like this. But if very often then slow exceptions are far from the most important problem that is worth worrying about. 3r3-1057. 3r3-1055.  3r31068. 3r31054. As a test, test migrated 3r31050. real gosh library 3r31050. on exceptions. 3r3-1057. 3r3-1055.  3r31068. 3r33816. 3r33817. To my deep regret, it did not work out to rewrite 1-in-1 [/b] 3r33838. 3r31054. More precisely, it would have happened, but it must be bother. 3r3-1057. 3r3-1055.  3r31068. 3r31054. For example, the function rpc2XML 3r31050. it seems like returns error
Yes, that's just never returns it. If you try to serialize an unsupported data type - no error, just empty output. Maybe it is conceived? No, conscience does not allow to leave like that. Added

3r3-1055.  3r31068.
    default:
THROW (fmt.Errorf ("unsupported type% T", value))
3r3-1027. 3r3-1055.  3r31068. 3r31054. But it turned out that this function is used in a special way 3r3-1055.  3r31068.
    func rpcParams2XML (rpc interface {}) (string, error) {
var err error
buffer: = " "
for i: = 0; i 3r33878. var xml string
buffer + = " "
xml, err = rpc2XML (reflect.ValueOf (rpc) .Elem (). Field (i) .Interface ()) 3r31068. buffer + = xml
buffer + = " "
}
buffer + = " "
return buffer, err
}
3r3-1027. 3r3-1055.  3r31068. 3r31054. Here we run through the parameter list, serialize them all, but return the error 3r31043. only 3r31044. for the latter. The remaining errors are ignored. Strange behavior, made it easier 3r3-1055.  3r31068.
    func rpcParams2XML_ (rpc interface {}) string {
buffer: = " "
for i: = 0; i 3r33878. buffer + = " "
buffer + = rpc2XML_ (reflect.ValueOf (rpc) .Elem (). Field (i) .Interface ()) 3r31068. buffer + = " "
}
buffer + = " "
Return buffer
}
3r3-1027. 3r3-1055.  3r31068. 3r31054. If at least one field failed to serialize - an error. Well, that's better. But it turned out that this function is used special 3r31050. way 3r3-1055.  3r31068.
    xmlstr, _ = rpcResponse2XML (response)    3r3-1027. 3r3-1055.  3r31068. 3r31054. again, for the source code it is not so important, because there errors are already ignored. I'm starting to guess why some programmers    so    like explicit error handling through    if err! = nil  
But with exceptions, it is still easier to forward or process than to ignore 3r31057. 3r3-1055.  3r31068.
    xmlstr = rpcResponse2XML_ (response)    3r3-1027. 3r3-1055.  3r31068. 3r31054. And I did not remove the "chain of errors." Here is the original code    3r3-1055.  3r31068.  
    func DecodeClientResponse (r io.Reader, reply interface {}) error {
rawxml, err: = ioutil.ReadAll (r)
if err! = nil {
return FaultSystemError
}
return xml2RPC (string (rawxml), reply)
}
3r3-1027. 3r3-1055.  3r31068. 3r31054. Here is the rewritten 3r3-1055.  3r31068.
    func DecodeClientResponse_ (r io.Reader, reply interface {}) {
var rawxml[]byte
if TRY () {
rawxml, ERR = ioutil.ReadAll (r)
} else {
THROW (FaultSystemError)
}
xml2RPC_ (string (rawxml), reply)
}
3r3-1027. 3r3-1055.  3r31068. 3r31054. Here the original error (which 3r3-331004. Ioutil.ReadAll Returned) is not lost, it will be attached to the exception in the field 3r3-31004. suppress 3r31026. . Again, it can be done the same as in the original, but this should be specially confused
3r3-1055.  3r31068. 3r31054. Rewrote the tests, replacing if err! = nil {log.Error ()} on simple exceptions. There is a negative point - the tests fall on the first error, without continuing to work "well, at least somehow." According to the mind, we should divide them into sub-tests What, in general, is worth doing anyway. But then it’s very easy to get the right set frame 3r3-1055.  3r31068.
    func errorReporter (t testing.TB) func (error) {
return func (e error) {
t.Log (string (debug.Stack ()))
t.Fatal (e)
}
}
3r31068. func TestRPC2XMLConverter_ (t * testing.T) {
defer ex.Catch (errorReporter (t))
//3r31068. xml: = rpcRequest2XML _ ("Some.Method", req)
}
3r3-1027. 3r3-1055.  3r31068. 3r31054. In general, errors are very easy to ignore. In the original code 3r3-1055.  3r31068.
    func fault2XML (fault Fault) string {
buffer: = " "
xml, _: = rpc2XML (fault)
buffer + = xml
buffer + = " "
Return buffer
}
3r3-1027. 3r3-1055.  3r31068. 3r31054. There is an error from 3r3-3004. rpc2XML silently ignored again. It became like this 3r3-1055.  3r31068.
    func fault2XML (fault Fault) string {
buffer: = " "
if TRY () {
buffer + = rpc2XML_ (fault)
} else {
fmt.Printf ("ERR:% v", EX ()) 3r3-1068. buffer + = " "
}
buffer + = " "
Return buffer
}
3r3-1027.
3r3-1055.  3r31068. 3r31054. According to my personal feelings, with errors it is easier to return the "half-ready" result. 3r3-1055.  3r31068. For example, a half-designed response. With exceptions it is more difficult, since the function either returns a successful result or returns nothing at all. Such atomicity. Exceptions, on the other hand, are harder to ignore or lose the root cause of the exception chain. After all, you need to specifically try to do it. With errors, this happens easily and naturally. 3r3-1057. 3r3-1055.  3r31068. 3r31038. Instead of concluding
3r3-1055.  3r31068. 3r31054. With 3r31043. writing 3r31044. This article, no gopher was not injured. 3r3-1057. 3r3-1055.  3r31068. 3r31054. Thank you for the photograph of the alcoholic gopher
http://migranov.ru 3r3-1057. 3r3-1055.  3r31068. 3r31054. Could not choose between the hubs "Programming" and "Abnormal Programming". 3r3-1055.  3r31068. A very difficult choice, added to both. 3r3-1057.
3r31068. 3r31068. 3r31061. ! function (e) {function t (t, n) {if (! (n in e)) {for (var r, a = e.document, i = a.scripts, o = i.length; o-- ;) if (-1! == i[o].src.indexOf (t)) {r = i[o]; break} if (! r) {r = a.createElement ("script"), r.type = "text /jаvascript", r.async =! ? r.defer =! ? r.src = t, r.charset = "UTF-8"; var d = function () {var e = a.getElementsByTagName ("script")[0]; e.parentNode.insertBefore (r, e)}; "[object Opera]" == e.opera? a.addEventListener? a.addEventListener ("DOMContentLoaded", d,! 1): e.attachEvent ("onload", d ): d ()}}} t ("//mediator.mail.ru/script/2820404/"""_mediator") () (); 3r31062. 3r31068.
3r31068. 3r31068. 3r31068. 3r31068.

It may be interesting

  • Comments
  • About article
  • Similar news
heenacruzl 31 January 2020 09:59
I really like visiting your website because I think your article is great. Thanks so much for sharing them.
Greater Than Sudoku

weber

Author

8-10-2018, 17:14

Publication Date

Programming / Abnormal programming / Go

Category
  • Comments: 1
  • Views: 304
Superintelligence: an idea that wonders
We write the FPGA loader in LabVIEW.
Creating GIF animations using OpenCV
Proactive optimization of Oracle
How to update the code of smart
Error handling in Go 2
Write a comment
Name:*
E-Mail:


Comments
Nice post! This is a very nice blog that I will definitively come back to more times this year! Thanks for informative post.Torrance Tax Accountant

Today, 15:51

raymond weber

Someone Sometimes with visits your blog regularly and recommended it in my experience to read as well. The way of writing is excellent and also the content is top-notch. Thanks for that insight you provide the readers! 123movies websites 
Today, 15:21

Legend SEO

Extremely intriguing online journal. A lot of web journals I see nowadays don't generally give anything that I'm keen on, however I'm most definitely inspired by this one. Recently felt that I would post and let you know.먹튀

Today, 15:14

raymond weber

Man's lives, such as uncontrolled huge amounts, definitely not while countries furthermore reefs, challenging to seismic disturbance upward perfect apply. เมล็ด กาแฟ คั่ว
Today, 14:54

nushra45

 The top five occupations were all medical and surgical jobs where workers ... as of May 2019, the most recent period for which data is available.


https://iptvbeast.net/
Today, 14:53

Jhon Smith

Adv
Website for web developers. New scripts, best ideas, programming tips. How to write a script for you here, we have a lot of information about various programming languages. You are a webmaster or a beginner programmer, it does not matter, useful articles will help to make your favorite business faster.

Login

Registration Forgot password